Почему std :: hex приводит к повреждению памяти vector.size ()? - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть следующий код:

vector<UINT_PTR> test = GetMemoryAddresses();

cout << "Size: " << test.size() << endl;

for (UINT_PTR a : test) {
    cout << "Memory Address: " << hex  << a << endl;
}

cout << "Size: " << test.size() << endl;

Который печатает следующие результаты:

Size: 18
Memory Address: fc06a0
Memory Address: 13a70f0
Memory Address: 36c78c1
Memory Address: 3da0ea0
Memory Address: 3e21b80
Memory Address: c0a6881
Memory Address: c747690
Memory Address: c748b98
Memory Address: c74a1b8
Memory Address: c74ce10
Memory Address: c750c78
Memory Address: 1340a10f
Memory Address: 14376ea0
Memory Address: 14472649
Memory Address: 69867268
Memory Address: 6bdf9243
Memory Address: 7399a142
Memory Address: 76c54875
Size: 12

Удаление

<< hex </p>

снова приводит к правильному vector.size () из 18.

Что вызывает этот разрыв памяти?

Я что-то не так сделал?

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

std::hex "липкий".Он устанавливает состояние потока в шестнадцатеричное отображение, и именно там он будет оставаться, пока вы не измените его.Это означает, что когда вы делаете

cout << "Size: " << test.size() << endl;

, вы отображаете размер в шестнадцатеричном формате, а 18 десятичное значение равно 12 шестнадцатеричным.

Вам необходимо

cout << "Size: " << dec << test.size() << endl;

, чтобы вернуться в десятичный режими отобразите размер «правильно».


Еще одна вещь, которая поможет вам диагностировать это, это использовать std::showbase.Это еще один «липкий» манипулятор, в котором шестнадцатеричный вывод будет добавлен 0x.Использование этого в

cout << "Memory Address: " << hex << showbase  << a << endl;

сделало бы ваш вывод

Size: 18
Memory Address: 0xfc06a0
Memory Address: 0x13a70f0
Memory Address: 0x36c78c1
Memory Address: 0x3da0ea0
Memory Address: 0x3e21b80
Memory Address: 0xc0a6881
Memory Address: 0xc747690
Memory Address: 0xc748b98
Memory Address: 0xc74a1b8
Memory Address: 0xc74ce10
Memory Address: 0xc750c78
Memory Address: 0x1340a10f
Memory Address: 0x14376ea0
Memory Address: 0x14472649
Memory Address: 0x69867268
Memory Address: 0x6bdf9243
Memory Address: 0x7399a142
Memory Address: 0x76c54875
Size: 0x12

, что делает намного более ясным, что последний вызов cout все еще использует hex

0 голосов
/ 20 февраля 2019
std::cout << std::hex;

делает все числа, напечатанные std::cout, в шестнадцатеричном формате.Чтобы снова вернуться к десятичному типу, выполните:

std::cout << std::dec;

В идеале перед использованием любых манипуляторов формата потока (например, std::hex) вы должны сохранить флаги форматирования и восстановить их, когда вы закончите.Например:

auto flags = std::cout.flags();
std::cout << std::hex << 10 << "\n";
std::cout.flags( flags );

Все флаги должны быть сброшены следующим образом: https://en.cppreference.com/w/cpp/io/ios_base/flags

Символ заполнения также является липким: https://en.cppreference.com/w/cpp/io/basic_ios/fill и точность тоже: https://en.cppreference.com/w/cpp/io/ios_base/precision

Единственное, что не является флагом ширины: https://en.cppreference.com/w/cpp/io/ios_base/width

У Boost есть служебный класс для сброса всех состояний потока обратно к начальным значениям: https://www.boost.org/doc/libs/1_69_0/libs/io/doc/ios_state.html

...