You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 01:06:03