使用内存分配和释放复制构造函数

时间:2013-12-03 12:37:01

标签: c++ memory-management copy-constructor allocation

我写了以下一段代码

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

///Driver class
class driver
{
    char *name;
    int age;
public:
    //Default contructor
    driver(){}

    //Constructor for initialize
    driver(int a, char* n)
    {
        age = a;
        int len = strlen(n);
        //Allocate memory for name
        name = new char[len];
        strcpy(name, n);
    }

    //Copy constructor
    driver(const driver &d)
    {
        name = new char[strlen(d.name)];
        strcpy(name, d.name);
        age = d.age;
    }

    void print()
    {
        cout<<"Name: "<<name<<endl;
        cout<<"Age: "<<age<<endl;
    }

    ~driver()
    {
        if(name != NULL)
        {
            delete name;
        }
    }
};

class automobile
{
    driver drv;
    char* make;
    int year;

public:
    automobile(driver d, char* m, int y)
    {
        drv = d;
        int len = strlen(m);
        make = new char[len];
        strcpy(make, m);
        year = y;
    }

    void print()
    {
        drv.print();
        cout<<"Make: "<<make<<endl;
        cout<<"Year: "<<year<<endl;
    }
    ~automobile()
    {
        if(make!=NULL)
        {
            delete[] make;
        }
    }
};

int main()
{
    driver d(15, "Jakir");
    automobile a(d, "Toyta", 1980);
    a.print();
    return 0;
}

我必须使用char *而不是字符串并动态分配内存。但是当我运行代码时,会出现内存泄漏错误。我认为这是由于驱动程序类的复制构造函数和解除分配内存。如何修复错误?任何建议表示赞赏。提前谢谢。

3 个答案:

答案 0 :(得分:2)

这段代码存在很多问题,但我会列出一些重要的代码。

  1. 正如其他人提到的,你new char需要比自己更大。
  2. 默认构造函数应将name设置为nullptr。
  3. 每次执行赋值时都会出现内存处理错误,例如在此行:drv = d;,因为它调用默认的operator =,这在您的情况下是不正确的。这就是三巨头的法则,它松散地指出,无论何时你需要一个(非平凡的)复制构造函数,复制赋值运算符或析构函数,你也很可能也需要实现其他的。你需要写一个operator =!
  4. 基于现有代码,我希望你的operator =看起来像这样:

    //assignment operator
    const driver&operator=(const driver &rhs)
    {
        if (this==&rhs) return *this;
        delete[] this->name;
        this->name = new char[strlen(rhs.name)+1];
        strcpy(this->name, rhs.name);
        this->age = rhs.age;
        return *this;
    }
    

    完成所有这些,你的核心转储就会消失。

    PS请,请学习使用std :: strings,new-ing char数组并自行管理内存是一个糟糕的坏举措。

答案 1 :(得分:0)

name = new char[len+1];不是name = new char[len];

name = new char[strlen(d.name) + 1];不是name = new char[strlen(d.name)];

delete[]不是delete

需要定义一个赋值运算符driver& operator=(const driver &d)才能遵循三个规则。

类似的更改需要automobile

但是我没有看到内存泄漏,是什么让你觉得你有一个呢?

答案 2 :(得分:0)

在main方法中你需要这样做,

driver* d = new driver(15, "Jakir");
automobile* a = new automobile (d, "Toyta", 1980);
a->print();
if ( a ) delete a ;
if ( d ) delete d ;
return 0 ;