为什么 std::hex 会导致内存损坏 vector.size()?
Why does std::hex lead to memory corruption vector.size()?
我有以下代码:
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
再次导致 18 的正确 vector.size()。
是什么导致了内存损坏?
我做错了什么吗?
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 and so is the precision: https://en.cppreference.com/w/cpp/io/ios_base/precision
唯一不是的是宽度标志:https://en.cppreference.com/w/cpp/io/ios_base/width
Boost 有一个实用程序 class 可以将所有流状态重置为初始值:https://www.boost.org/doc/libs/1_69_0/libs/io/doc/ios_state.html
std::hex
是 "sticky"。它将流的状态设置为十六进制显示,并且在您更改它之前它将一直停留在那里。这意味着当你做
cout << "Size: " << test.size() << endl;
您以十六进制显示大小,十进制的 18 是十六进制的 12。
你需要
cout << "Size: " << dec << test.size() << endl;
切换回十进制模式并显示大小 "correctly"。
另一个可以帮助您诊断的方法是使用 std::showbase
。它是另一个 "sticky" 操纵器,将在十六进制输出前添加 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
更加清楚
我有以下代码:
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
再次导致 18 的正确 vector.size()。
是什么导致了内存损坏?
我做错了什么吗?
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 and so is the precision: https://en.cppreference.com/w/cpp/io/ios_base/precision
唯一不是的是宽度标志:https://en.cppreference.com/w/cpp/io/ios_base/width
Boost 有一个实用程序 class 可以将所有流状态重置为初始值:https://www.boost.org/doc/libs/1_69_0/libs/io/doc/ios_state.html
std::hex
是 "sticky"。它将流的状态设置为十六进制显示,并且在您更改它之前它将一直停留在那里。这意味着当你做
cout << "Size: " << test.size() << endl;
您以十六进制显示大小,十进制的 18 是十六进制的 12。
你需要
cout << "Size: " << dec << test.size() << endl;
切换回十进制模式并显示大小 "correctly"。
另一个可以帮助您诊断的方法是使用 std::showbase
。它是另一个 "sticky" 操纵器,将在十六进制输出前添加 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