C++修改std::vector中Sales_data对象导致程序崩溃,求高效替代方案
问题分析
- 程序崩溃的根本原因:调用
vec.erase(it)后,迭代器it会直接失效,后续执行++it属于C++标准定义的未定义行为,大概率会触发内存访问错误导致崩溃。 - 可移植性问题:代码使用了
std::string却没有引入<string>头文件,部分编译器会直接编译失败。 - 实现效率问题:删除原有元素再插入新元素的操作会触发vector内部元素的移动,完全属于不必要的开销,同时代码还缺失了新增ISBN的插入逻辑,新的ISBN数据会直接丢失。
优化方案
你完全不需要删除原有对象,找到匹配的Sales_data对象后直接修改即可:你的combine成员方法本身就是设计用来将另一个Sales_data的销售数据合并到当前对象的,直接调用该方法就能完成更新,开销仅为两次算术运算,比删除+插入的方案效率高很多。
如果想保留原有的add方法,也可以直接赋值给找到的元素:*it = it->add(*it, book);,同样不需要删除插入操作。
修改后完整代码
#include <iostream> #include <vector> #include <string> struct Sales_data { std::string isbn() const{ return this->bookNo; } Sales_data& combine(const Sales_data &rhs) { this->units_sold += rhs.units_sold; this->revenue += rhs.revenue * rhs.units_sold; return *this; } std::string bookNo; unsigned units_sold = 0; double revenue = 0.0; }; int main() { Sales_data book; std::vector<Sales_data> vec; while(std::cin >> book.bookNo >> book.units_sold >> book.revenue) { bool existed = false; for(auto it = vec.begin(); it != vec.end(); ++it) { if(book.isbn() == it->isbn()) { // 直接修改原有对象,不需要删除插入 it->combine(book); existed = true; break; // 找到匹配项直接退出循环,避免无效遍历 } } // 没找到匹配的ISBN,插入新条目 if(!existed) { vec.push_back(book); } } return 0; }
内容的提问来源于stack exchange,提问作者Damo
相关产品推荐
相关产品推荐

