访问冲突 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&lt;T&gt; 中删除元素将使it 迭代器无效,因为std::vector&lt;T&gt; 对象将移动元素以在删除项目后保持底层数组连续。

幸运的是,vector&lt;T&gt;::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++ 中另一个对象中的对象

C++ - 使用 std::sort 对结构向量进行排序导致读取访问冲突

C++ Battle4Zion 项目抛出未处理的异常:读取访问冲突。 **this** 是 nullptr。发生了

从 C++ 调用 C DLL 会导致访问冲突,但 C# 项目与 DllImport 工作

C++ vector::clear() - 破坏顺序? [复制]

在 C++ 中删除多维结构会导致访问冲突