![](/img/trans.png)
[英]getting error "terminate called after throwing an instance of '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.