迭代抽象类Item指针类型vector时出现访问违例错误如何解决
问题根本原因
你当前存储的都是栈局部对象的野指针:
- 所有
Sofa newSofa/Bed newBed/Table newTable都是定义在if分支栈上的临时对象,离开if分支作用域后会被自动销毁 - 你存入
itemVector的只是这些临时对象的地址,后续访问时指向的内存已经被释放,就会触发0xC0000005访问越界错误,0xCCCCCCCC正是Windows平台调试模式下已释放栈内存的标记值。
修复方案
你需要把派生类对象分配到堆上延长生命周期,推荐优先用C++11及以后的智能指针自动管理内存,避免手动管理出现内存泄漏风险,不需要为每个派生类单独创建vector,依然可以统一存储所有Item子类对象:
步骤1:修改vector的存储类型
把原来的vector<Item*>改为vector<unique_ptr<Item>>。
步骤2:修改AddItem逻辑,用堆分配替代栈临时对象
修改后的代码如下:
void ItemVector::AddItem() { string Answer = "y"; while (Answer == "y") { cout << "Would you like to register a sofa to the warehouse stock (y/n)?" << endl; cin >> Answer; if (Answer == "y") { // 堆分配Sofa对象,用智能指针自动管理生命周期 itemVector.push_back(make_unique<Sofa>()); } else if (Answer != "n") Answer = "y"; } Answer = "y"; while (Answer == "y") { cout << "Would you like to register a bed to the warehouse stock (y/n)?" << endl; cin >> Answer; if (Answer == "y") { itemVector.push_back(make_unique<Bed>()); } else if (Answer != "n") Answer = "y"; } Answer = "y"; while (Answer == "y") { cout << "Would you like to register a table to the warehouse stock (y/n)?" << endl; cin >> Answer; if (Answer == "y") { itemVector.push_back(make_unique<Table>()); } else if (Answer != "n") Answer = "y"; } }
步骤3:调整DisplayInfo的遍历逻辑
void ItemVector::DisplayInfo() { vector<unique_ptr<Item>>::const_iterator pos; int i = 0; for (pos = itemVector.begin(); pos != itemVector.end(); ++pos) { cout << "Item number " << ++i << " has the following details:\n"; (*pos)->printDetails(); } }
如果你的编译环境不支持C++11,可以用原始指针new分配对象,但是要记得在ItemVector的析构函数里遍历vector逐个delete所有指针避免内存泄漏。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

