来自 Lambda 的访问冲突偶尔会出现
Access Violation from Lambda occasionally exhibits itself
我有一个lambda,当我尝试从std::vector
中删除对象时,它偶尔会导致访问冲突。我将要删除的对象的副本传递给 lambda 而不是迭代器,因为迭代器可能不会在执行时间指向正确的对象。
有没有更好的方法来设置 lambda 以从向量中删除特定对象?这里访问违规的确切原因是什么?很难调试,因为在此错误期间调试时,局部变量和自动变量为空/损坏。
... std::vector<CustomLayout> customLayouts; // private class member variable
void App::loadCustomLayouts() {
CustomLayout customLayout;
// ... create HWND
onMessage(WM_RBUTTONDOWN, [customLayout, this]() {
auto it = std::remove(customLayouts.begin(), customLayouts.end(), customLayout);
customLayouts.erase(it); // occasionally causes access violation
});
}
您没有遵循正确的remove
习语。很简单:
vec.erase(std::remove_if(vec.begin(), vec.end(), elem), vec.end());
您无需减去任何内容或执行任何自定义分支。
std::remove 返回删除所有等于 customLayout
的值的范围的结束迭代器。它实际上不会删除任何内容,它只是更改元素位置,以便将"删除"的元素放置在新范围的结束迭代器之后。但是,"已删除"元素的状态是未指定的,引用它们可能会导致问题。
然后,就 STL 而言,结束迭代器指向范围最后一个元素旁边的元素,而不是最后一个元素本身。这就是为什么任何使用结束迭代器的操作(在您的情况下it
)都是无效的。
最可能的错误情况是当customLayouts
不包含等于 customLayout
的元素时。然后it
指向一个从未存在过的元素,erase
试图摧毁它。
如果要erase
新(较短)范围的最后一个元素,则应编写customLayouts.erase(it - 1);
。
相关文章:
- 写入位置0x0000000C时发生访问冲突
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 链表中写入访问冲突的未知原因
- C++中的openCV Mat访问冲突
- C++尝试深度复制唯一指针时出现内存访问冲突
- C++ 中动态二维数组的访问冲突
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 写入访问冲突异常
- 在类 12.exe 中0x7B37FF80 (ucrtbased.dll) 引发异常: 0xC0000005:访问冲突读
- 0xC0000005:访问冲突写入位置0xCDCDCDCD动态分配错误
- 读取访问冲突.这0xCDCDCDCD
- 0xC0000005:访问冲突读取位置 0x00000000. 重载 == 运算符的问题
- 插入数组时违反写访问冲突
- 使用 ReadProcessMemory 获取字符串值的访问冲突
- 尝试通过共享指针使用变量时读取访问冲突
- 堆栈上的 C++ 访问冲突写入异常
- 引发异常:写访问冲突. temp 为 nullptr
- 将静态字符数组中的字符分配给动态分配的字符数组 - 访问冲突
- 在C++中删除双向链表的头节点后出现访问冲突异常
- 来自 Lambda 的访问冲突偶尔会出现