作为实践,我正在尝试从我用C++编写的内存扫描仪中删除不匹配的结果。当最初扫描内存时,所有结果都存储在_results向量中。
稍后,将再次扫描_results,并应删除不再匹配的项。
错误:
.exe: 0xC0000005:访问冲突读取位置0x0090c000中0x004016f4处的未处理异常。
// Receives data
DWORD buffer;
for (vector<memblock>::iterator it = MemoryScanner::_results.begin(); it != MemoryScanner::_results.end(); ++it) {
// Reads data from an area of memory into buffer
ReadProcessMemory(MemoryScanner::_hProc, (LPVOID)(*it).address, &buffer, sizeof(buffer), NULL);
if (value != buffer) {
MemoryScanner::_results.erase(it); // where the program breaks
}
}发布于 2011-01-14 03:33:22
从std::vector<T>中擦除元素将使it迭代器失效,因为std::vector<T>对象将在删除项后移动元素以保持底层数组的连续性。
幸运的是,vector<T>::erase()返回一个新的、有效的迭代器,这样您就不会试图取消无效迭代器的引用:
DWORD buffer;
vector<memblock>::iterator it = MemoryScanner::_results.begin();
while(it != MemoryScanner::_results.end())
{
ReadProcessMemory(MemoryScanner::_hProc, (LPVOID)(*it).address,
&buffer, sizeof(buffer), NULL);
if (value != buffer)
{
it = MemoryScanner::_results.erase(it);
}
else
{
++it;
}
}另一种删除向量中的项的方法
您考虑过使用擦除成语吗?
struct RemoveNonMatches
{
public:
RemoveNonMatches(HANDLE p, DWORD v) : proc(p) val(v) {}
bool operator()(const memblock& obj)
{
DWORD buffer;
ReadProcessMemory(proc, static_cast<LPVOID>(obj.address),
&buffer, sizeof(buffer), NULL);
return (buffer != val);
}
private:
HANDLE proc
DWORD val;
};
// ...
MemoryScanner::_results.erase
(
std::remove_if
(
MemoryScanner::_results.begin(),
MemoryScanner::_results.end(),
RemoveNonMatches(MemoryScanner::_hProc, value)
),
MemoryScanner::_results.end()
);发布于 2011-01-14 03:34:25
vector::erase使传递给erase()的迭代器无效。然后尝试增加它。UB接踵而来。
发布于 2011-01-14 03:51:53
为了完整起见,std::remove_if版本:
bool has_bad_memory_contents(const memblock& block) {
DWORD buffer;
ReadProcessMemory(
MemoryScanner::_hProc, (LPVOID)block.address,
&buffer, sizeof(buffer), NULL
);
return buffer != value;
}
std::vector<memblock>& r = MemoryScanner::_results;
r.erase(std::remove_if(r.begin(), r.end(), has_bad_memory_contents), r.end());https://stackoverflow.com/questions/4687731
复制相似问题