c++ 在分配变量时未处理的异常访问冲突

Posted

技术标签:

【中文标题】c++ 在分配变量时未处理的异常访问冲突【英文标题】:c++ unhandled exception access violation at assigning variable 【发布时间】:2015-09-14 17:07:27 【问题描述】:
std::vector <Item*> itemSlot;
itemSlot.resize(1);

Item testItem;
testItem.item_id = 99;

*itemSlot[0] = testItem;        // ERROR

std::cout << "ID: " << itemSlot[0]->item_id << std::endl;

为什么会出错?

我知道我可以做到:

itemSlot[0] = &testItem;

但我不想这样做,因为如果我在函数中创建项目并在函数中分配它,如果我在函数外部调用 itemSlot[0]->item_id,它会给我随机数,因为变量 item 会被销毁,并且指针不会指向任何东西。

【问题讨论】:

【参考方案1】:

意义

*itemSlot[0] = testItem; // Copy-assign testItem into the item at index zero

完全不同
itemSlot[0] = &testItem; // Place the address of testItem at index zero

如果您在索引 0 处有一个 Item,则第一个构造将起作用,但您不这样做:对 itemSlot.resize(1) 的调用将 nullptr 放入索引零,因此取消引用它会导致未定义的行为。

有几种可用的解决方案:

vector 设为Item 的向量,而不是Item*,或者 使用Item *testItem = new Item(),最后调用delete,或者 将new Item() 与智能指针向量一起使用以避免手动删除。

【讨论】:

你在想reserve(1)resize(1) 确实改变了向量的大小。 @JonathanWakely 你说的很对,我编辑来纠正这个问题。【参考方案2】:

你有指向项目的指针向量。这样做通常是个坏主意。共享指针会更好。如果你想使用指针,那么你应该为它们分配内存,所以你应该这样做:

itemSlot[0] = new Item;

在访问它之前。更好看的是:

Item* tmpItem = new Item;
itemSlot.push_back(tmpItem);

之后不要忘记释放内存。改用共享指针或唯一指针


另一种方式:

itemSlot[0] = &testItem;

这也可以,但是在 testItem 停止后,现有向量仍将指向内存中的某个位置。

【讨论】:

以上是关于c++ 在分配变量时未处理的异常访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

捕获访问冲突异常?

使用 getenv 检索不存在的环境变量时出现访问冲突异常

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

抛出异常:写访问冲突 C++

C++:XY.exe 中 0x0b9ec715 (XX.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0x00000004

WindowsError 异常访问冲突 - 在简单的 python c++ ctypes 接口中