访问冲突 C++(删除向量中的项目)
Posted
技术标签:
【中文标题】访问冲突 C++(删除向量中的项目)【英文标题】:Access violation C++ (Deleting items in a vector) 【发布时间】:2011-01-14 03:29:57 【问题描述】:我正在尝试从我用 C++ 编写的内存扫描仪中删除不匹配的结果作为练习。最初扫描内存时,所有结果都存储到_results
向量中。
稍后,_results
将再次被扫描,并应删除不再匹配的项目。
错误:
在 0x004016f4 处未处理的异常 .exe:0xC0000005:访问 违规读取位置0x0090c000。
// 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
【问题讨论】:
提供的代码似乎不够完整,无法回答问题。 我认为类型无关紧要,因为它是明确指向擦除行的访问冲突。 【参考方案1】:从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;
另一种删除向量中项目的方法
您是否考虑过使用erase-remove idiom?
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()
);
【讨论】:
it = MemoryScanner::_results.erase(it);
没有修复它
啊,我忘记了 else 语句。谢谢你。【参考方案2】:
vector::erase
使您传递给 erase()
的迭代器无效。然后,您尝试增加它。 UB 随之而来。
【讨论】:
【参考方案3】: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());
【讨论】:
以上是关于访问冲突 C++(删除向量中的项目)的主要内容,如果未能解决你的问题,请参考以下文章
C++ - 使用 std::sort 对结构向量进行排序导致读取访问冲突
C++ Battle4Zion 项目抛出未处理的异常:读取访问冲突。 **this** 是 nullptr。发生了
从 C++ 调用 C DLL 会导致访问冲突,但 C# 项目与 DllImport 工作