簡體   English   中英

從向量中刪除指針...錯誤:在拋出“std::bad_alloc”實例后調用終止 what(): std::bad_alloc

[英]Deleting a pointer from a vector... Error: terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc

從向量中刪除一個指針並嘗試刪除第二個指針后出現錯誤。 我對指針還是陌生的

我創建了一個基本形狀 class 並且有多個形狀派生類未在此處顯示,我必須將它們存儲在指針向量中。

我要求用戶添加他們選擇的形狀並計算體積然后我還詢問他們想要刪除什么形狀。

#include <string>
#include <iostream>
#include <vector>
#include <iomanip>
#define _USE_MATH_DEFINES
#include <cmath>

using namespace std;

class Luggage {
    private:
        static double totalVolume;
    
    protected:
        string type;
        static int count;
        static int serialGen;
        int serialNum;
    
    public:
        Luggage() {
            type = "Luggage";
            count++;
            serialNum = serialGen++;
            cout<<"Generating Luggage"<<getSN()<<endl;
        }
        
        // 'static' can only be specified in the class header file not source
        void static updateVolume(double inVolume) {
            totalVolume += inVolume;
        }
        
        virtual 
        ~Luggage() {
            cout<<"Luggage Destructor"<<getSN()<<endl;
            count--;
        }
        
        static int getCount() {
            return count;
        }
        
        string getType() {
            return type;
        }
        
        string getSN() {
            return "(SN: " + to_string(serialNum) + ")";
        }
        
        virtual double getVolume()=0;
        
        static double getLuggageVolume() {
            return totalVolume;
        };
        
        friend ostream & operator<<(ostream & out, Luggage * lptr) {
            out<<setw(10)<<left<<lptr->getType()<<": "
                <<setw(6)<<right<<setprecision(1)
                <<fixed<<lptr->getVolume()<<"  ~  "<<lptr->getSN();
            return out;
        }
};



class Box : public Luggage {
    private:
        double length, width, height;
        static int count;
        static double totalVolume;
        
    public:
        Box(double l, double w, double h){
            count++;
            type = "Box";
            length = l;
            width = w;
            height = h;
            cout<<"Generating a Box with a Volume: "<<getVolume()<<getSN()<<endl;
            updateVolume(getVolume());
        }
        
        ~Box() {
            count--;
            updateVolume(getVolume() * -1);
            cout<<"Destroying a Box with Volume: "<<getVolume()<<getSN()<<endl;
        }
        
        double getVolume() {
            return length*width*height;
        }
        
        static int getCount() {
            return count;
        }
        static double getTotalVolume() {
            return totalVolume;
        }
};


int main() {
    // Your main program will create a container of luggage and be able to add luggage items
    // and remove them as well. This container will be a vector of luggage pointers.
    vector<Luggage*> container;

    int input;  // Main Menu User input
    bool io = true;
    while(io){
        // Main Menu
        cout << "\n----Main Menu----\n"
                "1) Add Luggage to storage container\n"
                "2) Remove Luggage from storage container\n"
                "3) Show all luggage\n"
                "4) Show total volumes\n"
                "5) Exit\n\n"
                "Enter: ";
        Luggage *lptr;

        cin >> input;
        if(input == 1){
            int shapeChoice;
            cout<<"\nWhat Shape do you want? "<<endl
                    <<"1) Box"<<endl
                    <<"2) Cube"<<endl
                    <<"3) Cylinder"<<endl
                    <<"4) Pyramid"<<endl
                    <<"5) Sphere"<<endl;
            cin>>shapeChoice;

            switch (shapeChoice){
                case 1: {   // Box
                    double length, width, height;
                    cout << "\nEnter length of Box: ";
                    cin >> length;
                    cout << "Enter width of Box: ";
                    cin >> width;
                    cout << "Enter height of Box: ";
                    cin >> height;
                    lptr = new Box(length, width, height);
                    container.push_back(lptr);
                    break;
                }
                default:
                    cout << "Bad choice! Please try again later.\n";
                    break;
            }

        }else if(input == 2) {

            int count = 0;
            for(auto l:container) // container is vector<Luggage*>
                cout << ++count << ") "<< l << endl;

            cout<<"What element do you want to remove? "<<endl;
            int removeChoice;
            cin>>removeChoice;
            removeChoice-=1;

            delete (lptr);
            container.erase(container.begin()+removeChoice);

        }
}

delete (lptr);

這種說法是錯誤的。

lptr指向最后一個推入向量的Box object。 如果尚未推送任何內容,則此語句會導致未定義的行為,因為lptr在第一次推送之前未初始化。 否則,您將銷毀最后推送的 object,然后留下一個懸空指針,該指針將在下一次delete時失敗,再次導致未定義的行為,除非您推送一個預先更新lptr的新 object。

該聲明應該是這樣的:

delete container[removeChoice];

或更安全:

delete container.at(removeChoice);

因為您沒有事先驗證removeChoice

但無論哪種方式,你真的不應該在現代 C++ 中手動new / delete對象。改用智能指針,在本例中為std::unique_ptr<Luggage> ,讓它為你處理銷毀對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM