微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Std::bad_alloc 在 While 循环中间抛出

如何解决Std::bad_alloc 在 While 循环中间抛出

我正在编写一个处理订单输入文件 (csv) 的函数,该函数使用 while 循环进行迭代。

ID,campaign,merchant,date
1,"hello 01/01/2021 02:22:22",260
2,"hello 01/01/2021 02:22:32",260

每两行代表一个输入。我有以下函数来处理这个输入:

762212,1,2020-03-15,10951-3,64612-2,57544-1,80145-1,27515-2,16736-1,79758-2,29286-2,51822-3,39096-1,32641-3,63725-3,64007-2,23022-1,16974-3,26860-2,75536-2,26461-1
1,373975319551257,12-2023
258572,2,96497-1,70616-1,80237-2,22248-2,56107-1,59695-1,37948-3,21316-3,63498-1,18329-1,56833-1,66295-1,47680-3,30346-1
1,201741963232463,02-2022
857003,3,16655-1,88019-3,75069-3,96017-2,46883-2,15138-1,77316-1,70063-3,54452-3,86429-2,15134-2,60176-1,12946-3
2,cfeeham3s
747893,4,2020-03-17,48520-1,93268-2,63636-1,23750-2,99771-3,83203-1,89921-2,15134-3,82831-1,30346-2,54044-3,28561-1,14792-2,23523-3,56826-2
1,3571379825697064,04-2025

由于我的 cout 语句,我可以看出它在遇到 std::bad_alloc 错误之前只将两个项目添加到列表中。当它在初始化时从添加 list<Order> orders; void read_orders(string file_name) { fstream read_file; read_file.open(file_name,ios::in); if (read_file.is_open()) { string s; int line_num = 1; // keeps track of line number in input file int o_id; string o_date; int c_id; vector<LineItem> itms; while (getline(read_file,s)) { cout << orders.size(); // shows that only two objects are added before failure if (line_num % 2 == 1) { // handle odd numbered lines of input auto data = split(s,','); int o_id = stoi(data[0]); string o_date = data[1]; int c_id = stoi(data[2]); vector<LineItem> itms; // get line items int n_line_items = data.size() - 3; vector<string> end_data(data.end() - n_line_items,data.end()); for (string x: end_data) { auto parts = split(x,'-'); LineItem* it = new LineItem(stoi(parts[0]),stoi(parts[1])); itms.push_back(*it); delete it; } } else { // handle even numbered lines of input auto data = split(s,'); Credit* pay_credit = new Credit(0.0,data[1],data[2]); // initialize each type of payment PayPal* pay_paypal = new PayPal(0.0,data[1]); WireTransfer* pay_wire = new WireTransfer(0.0,data[2]); if (data[0] == "1") { Order* ordr = new Order(o_id,o_date,c_id,itms,*pay_credit); orders.push_back(*ordr); delete ordr; } else if (data[0] == "2") { Order* orr = new Order(o_id,*pay_paypal); orders.push_back(*orr); delete orr; } else if (data[0] == "3") { Order* odr = new Order(o_id,*pay_wire); orders.push_back(*odr); delete odr; } delete pay_credit; // trying to clean up memory delete pay_paypal; delete pay_wire; } line_num += 1; } read_file.close(); } } 对象切换到将 Credit 对象添加PayPal 时,似乎会发生这种情况。我对为什么会发生这种情况进行了大量研究,所以我尝试尽可能多地清理(我是 C++ 新手),但同样的错误不断出现。错误是在我向列表中添加内容时发生还是在我创建这些新对象时发生?/我该如何解决此类问题?

这是我的类定义,以防万一:

Order(...)

这是显示它确实插入了两个项目的错误消息:

class Payment {
public:
    double amount;
    string print_detail() {
        return "hey";
    };
};

class Credit: public Payment {
private:
    string card_number;
    string expiration;
public:
    Credit(double amt,string cn,string exp) {
        this->amount = amt;
        this->card_number = cn;
        this->expiration = exp;
    }
    string print_detail() {
        return "Credit card " + this->card_number + ",exp. " + this->expiration;
    }
};

class PayPal: public Payment {
private:
    string paypal_id;
public:
    PayPal(double amt,string pp_id) {
        this->amount = amt;
        this->paypal_id = pp_id;
    }
    virtual string print_detail() {
        return "Paypal ID: " + this->paypal_id;
    }
};

class WireTransfer: public Payment {
private:
    string bank_id;
    string account_id;
public:
    WireTransfer(double amt,string b_id,string a_id) {
        this->amount = amt;
        this->bank_id = b_id;
        this->account_id = a_id;
    }
    string print_detail() {
        return "Wire transfer from Bank ID " + this->bank_id + ",Account# " + this->account_id;
    }
};

class LineItem {
private:
    int item_id;
    int qty;
public:
    LineItem(int i_id,int qt) {
        this->item_id = i_id;
        this->qty = qt;
    }
    double subtotal() {
        double subtot = 0.0;
        for (auto x: items) {
            if (x.item_id == this->item_id) {
                subtot += x.price * this->qty;
            }
        }
        return subtot;
    };
};

class Order {
private:
    int order_id;
    string order_date;
    int cust_id;
    vector<LineItem> line_items;
    Payment payment;
public:
    Order(int o_id,string o_date,int c_id,vector<LineItem> li,Payment pay) {
        this->order_id = o_id;
        this->order_date = o_date;
        this->cust_id = c_id;
        this->line_items = li;
        this->payment = pay;
    }
    string pay_type = "";

    double total() {
        double result = 0.0;
        for (auto li: line_items) {
            result += li.subtotal();
        }
        return result;
    }
    string print_order() {
        string text = "===========================\norder #";
        text += to_string(this->order_id) + ",Date: " + this->order_date + "\nAmount: $";
        text += to_string(this->total()) + ",Paid by ";
        text += payment.print_detail();
        return text;
    }
};

解决方法

std::bad_alloc 在没有足够的内存分配时经常被抛出。我不能说这是否能解决问题,但是您对对象的重复分配和释放既不必要又有害(导致内存碎片)。

代替

LineItem* it = new LineItem(stoi(parts[0]),stoi(parts[1]));
itms.push_back(*it);
delete it;

你应该这样做

itms.push_back(LineItem(stoi(parts[0]),stoi(parts[1]));

itms.emplace_back(stoi(parts[0]),stoi(parts[1]));

这同样适用于 new 中每次出现的 read_orders。你不需要它们中的任何一个。


您可以做的另一件事是为 std::vector 预分配内存。如果您不知道它将包含多少项,请进行有根据的猜测(100、1000、10000 等)。

itms.reserve(1000); //before you start to push_back() to it

另外,如果您想传输全部内容而不是复制,请确保std::move您的矢量。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?