首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >访问冲突C++ (删除向量中的项)

访问冲突C++ (删除向量中的项)
EN

Stack Overflow用户
提问于 2011-01-14 03:29:57
回答 3查看 1.8K关注 0票数 0

作为实践,我正在尝试从我用C++编写的内存扫描仪中删除不匹配的结果。当最初扫描内存时,所有结果都存储在_results向量中。

稍后,将再次扫描_results,并应删除不再匹配的项。

错误:

.exe: 0xC0000005:访问冲突读取位置0x0090c000中0x004016f4处的未处理异常。

代码语言:javascript
复制
// 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
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-14 03:33:22

std::vector<T>中擦除元素将使it迭代器失效,因为std::vector<T>对象将在删除项后移动元素以保持底层数组的连续性。

幸运的是,vector<T>::erase()返回一个新的、有效的迭代器,这样您就不会试图取消无效迭代器的引用:

代码语言:javascript
复制
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;
    }
}

另一种删除向量中的项的方法

您考虑过使用擦除成语吗?

代码语言:javascript
复制
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()
);
票数 5
EN

Stack Overflow用户

发布于 2011-01-14 03:34:25

vector::erase使传递给erase()的迭代器无效。然后尝试增加它。UB接踵而来。

票数 1
EN

Stack Overflow用户

发布于 2011-01-14 03:51:53

为了完整起见,std::remove_if版本:

代码语言:javascript
复制
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());
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4687731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档