C++ 类中的动态内存分配问题

C++ 类中的动态内存分配问题,c++,class,c++11,dynamic-memory-allocation,freeze,C++,Class,C++11,Dynamic Memory Allocation,Freeze,我正在尝试为一家比萨饼餐厅创建一个类,其中我为比萨饼创建了一个单独的类,为该餐厅创建了另一个类。restaurant类有一个动态数组,类型为Pizza,每当餐厅中添加另一个Pizza时,其大小都会增加 每当我执行该程序时,它都会在创建新对象之前停止for循环中的工作,并且调用addPizza()函数时不会给出错误或任何信息。我还是一个编程新手,所以我想我可能分配的内存不正确,从而导致它冻结。有人能帮我弄清楚我做错了什么吗 多谢各位 #include <iostream> #inclu

我正在尝试为一家比萨饼餐厅创建一个类,其中我为
比萨饼
创建了一个单独的类,为该餐厅创建了另一个类。restaurant类有一个动态数组,类型为
Pizza
,每当餐厅中添加另一个Pizza时,其大小都会增加

每当我执行该程序时,它都会在创建新对象之前停止for循环中的工作,并且调用
addPizza()
函数时不会给出错误或任何信息。我还是一个编程新手,所以我想我可能分配的内存不正确,从而导致它冻结。有人能帮我弄清楚我做错了什么吗

多谢各位

#include <iostream>
#include <cstring>
#include <string>

using namespace std;

class Pizza {
private:
    char name[15];
    int price;
    char *ingredients;
    int reduction;
public:
    Pizza (char  *name= "", int price= 0, char *ingredients= "", int reduction= 0) {
        this->ingredients= new char [strlen(ingredients)+1];
        strcpy(this->ingredients, ingredients);
        strcpy(this->name, name);
        this->price= price;
        this->reduction= reduction;
    }
    ~Pizza () {
        delete [] ingredients;
    }
    bool areSame(Pizza p) {
        for (int i = 0; i < strlen(this->ingredients) + 1; i++) 
            if (this->ingredients[i] != p.ingredients[i])
                return true;
        return false;            
    }

    int getReduction() {
        return reduction;
    }

    void print() {
        cout << "name: " << name<< " ingredients: " << ingredients<< " Price: " << price;
    }
};

class Pizzeria{
private:
    char name[15];
    Pizza *p;
    int number_of_pizzas;
public:
    Pizzeria(char *name= "") {  
        strcpy(this->name, name);
        p = new Pizza [0];
        number_of_pizzas = 1;
    }

    Pizzeria(const Pizzeria &x) {
        this->p = new Pizza [x.number_of_pizzas-1];
        for (int i = 0; i < number_of_pizzas; i++) {
            this->p[i] = x.p[i];
        }
        this->number_of_pizzas= x.number_of_pizzas;
        strcpy(this->name, x.name);
    }   

    ~Pizzeria() {
        delete [] p;
    }

    void addPizza(Pizza P) {cout<<"fsfas";
        for (int i = 0; i < number_of_pizzas; i++) {
            if (!(p[i].areSame(P))) {
                number_of_pizzas++;
                p[number_of_pizzas] = P;
                return;
            }
        }
    }

    void pizzasOnPromotion() {
        for (int i = 0; i < number_of_pizzas; i++)
            if (p->getReduction() > 0)
                p->print();
    }

    void setName(char *name) {
        strcpy(this->name, name);
    }
    char getName() {
        return *name;
    }
};

int main () {

int n;
char name[15]; 
Pizzeria p1(name);
cin >> name;
cin >> n;
int reduc;

for(int i = 0; i < n; i++){
    char imp[100];
    cin.get();
    cin.getline(imp,100);
    int price;
    cin >> price;
    char ingredients[100];
    cin.get();
    cin.getline(ingredients,100);
    cin >> reduc;   cout << "pls work";
    Pizza p(imp,price,ingredients,reduc);

    p1.addPizza(p);
}

Pizzeria p2 = p1;
cin >> name;
p2.setName(name);
char imp[100];
cin.get();
cin.getline(imp,100);
int price;
cin >> price;
char ingredients[100];
cin.get();
cin.getline(ingredients,100);
cin >> reduc;
Pizza p(imp,price,ingredients,reduc);
p2.addPizza(p);

cout<<p1.getName()<<endl;
cout<<"Pizzas on promotion:"<<endl;
p1.pizzasOnPromotion();

cout<<p2.getName()<<endl;
cout<<"Pizzas on promotion:"<<endl;
p2.pizzasOnPromotion();
return 0;
}
#包括
#包括
#包括
使用名称空间std;
高级披萨{
私人:
字符名[15];
国际价格;
炭*成分;
整数归约;
公众:
比萨饼(char*name=,int-price=0,char*components=,int-reduction=0){
这->成分=新字符[strlen(成分)+1];
strcpy(这个->成分,成分);
strcpy(此->名称,名称);
这个->价格=价格;
这->减少=减少;
}
~Pizza(){
删除[]种成分;
}
布尔阿瑞森(披萨p){
对于(inti=0;icomponents)+1;i++)
如果(此->成分[i]!=p.Components[i])
返回true;
返回false;
}
int getreduce(){
收益减少;
}
作废打印(){
不能打印();
}
无效集合名(字符*名称){
strcpy(此->名称,名称);
}
char getName(){
返回*名称;
}
};
int main(){
int n;
字符名[15];
比萨店p1(名称);
cin>>名称;
cin>>n;
int-reduce;
对于(int i=0;i>价格;
煤焦成分[100];
cin.get();
cin.getline(成分,100);
cin>>还原;cout>名称;
p2.集合名(名称);
char-imp[100];
cin.get();
cin.getline(imp,100);
国际价格;
cin>>价格;
煤焦成分[100];
cin.get();
cin.getline(成分,100);
cin>>还原;
比萨p(进口、价格、配料、减量);
p2.2(p);

不能肯定这是你的问题,但这是一个(大!)问题

您的
类在构造函数中动态分配内存

this->ingredients= new char [strlen(ingredients)+1];
但是没有(a)复制构造函数,(b)移动构造函数,(c)操作符=(Pizza const&)
和(d)操作符=(Pizza&&)

这保证了你的问题;大问题

可能会给你带来问题的一点是
类Pizzeria
(顺便说一句:另一个具有动态内存分配的类,一个不错的复制构造函数,但没有(a)移动构造函数,(b)
操作符=(Pizzeria const&)
和(d)
操作符=(Pizzeria&&
),其中,在复制构造函数中,你有

this->p[i] = x.p[i];
在这个指令(调用隐式
操作符=(Pizza const&)
)之后,您有
this->p[i]
x.p[i]
,它们对于
配料具有相同的值

当调用第一个函数的析构函数时没有问题。但是当调用第二个函数的析构函数时,在相同的分配值上有一个双自由度,这是未定义的行为,但通常会使程序崩溃

一些建议

您标记了C++11,因此可以使用智能指针(
std::unique\u ptr
std::shared\u ptr

在可能的情况下,避免直接管理动态分配的内存,并使用
std::string
和STL容器(例如:在
class Pizzeria
中为
配料使用
std::string
,为
比萨饼使用
vector

当无法避免管理动态分配的内存时,请使用智能指针


当你被迫(但实际上是被迫)直接使用
new
delete
时,记得复制和移动构造函数和
操作符=()
,我不知道你到底想用第二节课做什么,但你可以按如下方式重写第一节课,那么头痛的事就不会有一半了

#include <iostream>
#include <string>
using namespace std;

class Pizza
{
private:
    string name;
    int price;
    int reduction;
    string ingredients;
public:
    Pizza (const string& name, const int& price, const int& reduction,
           const string& ingredients)
        :name(name), price(price), reduction(reduction), ingredients(ingredients)
        {}
    ~Pizza () {}

    bool areSame(const Pizza& p)const
    {   return this->ingredients == p.ingredients;     }

    const int& getReduction()const {    return reduction;}

    void print()
    {
        cout << "name: " << name<< " ingredients: " << ingredients<< " Price: " << price;
    }
};

你尝试过使用调试器吗?我还不知道如何使用调试器。就像我说的,我对编程完全陌生。1)如果你尝试使用调试器单步执行代码,你就不需要猜测问题出在哪里。你会知道的。2)“我还不知道如何使用调试器”那么,是什么阻止了你学习这些呢?我认为你是一个全新的人——这就是为什么我指出,解决这个问题以及你将面临的许多其他类似情况的真正办法是尽快学会如何自己调试问题,而不是让互联网上的人帮你解决问题。你知道你的代码,你知道吗有了你的代码,你就可以调试你的代码;其他人有一个严重的缺点,每次遇到挫折都要问他们,这会在双方都浪费很多时间。动态内存分配的根源在于你使用的是
char
数组或指向C样式字符串的指针。使用
std::string
,这样你就不必为动态性而烦恼了c内存分配。
class Pizzeria
{
private:
    string name;
    int number_of_pizzas;
    Pizza *p;
public:
    Pizzeria() = default;

    Pizzeria(const string& name)
        :name(name), number_of_pizzas(0), p(nullptr)    {}

    Pizzeria(const string& name, const int& number, Pizza *p)
        :name(name), number_of_pizzas(number), p(p)     {}

    // hope, you wanted a copy constructor here.
    Pizzeria(const Pizzeria &x)
        :name(x.name), number_of_pizzas(x.number_of_pizzas)
    {
        this->p = new Pizza(*x.p);
    }

    ~Pizzeria() {   delete[] p;    }

    void addPizza(Pizza P)
    {
       //explain the concept
    }

    void pizzasOnPromotion()
    {
        //explain the concept
    }

    void setName(const string& name) {  this->name = name;  }
    const string& getName()const  { return name;    }
};