【问题标题】:Copy constractor with memory allocation and deallocation具有内存分配和释放的复制构造函数
【发布时间】:2013-12-03 12:37:01
【问题描述】:

我写了以下代码

#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* 而不是字符串并动态分配内存。但是当我运行代码时,会出现内存泄漏的错误。我认为这是由于驱动程序类的复制构造函数和取消分配内存。如何修复错误?任何建议表示赞赏。提前致谢。

【问题讨论】:

  • 你没有遵循三法则,而且,delete nullptr; 是一个空操作。
  • delete [] name;,不是delete name;
  • 您总是分配一个char 太少;请记住,C 风格的字符串有一个终止符 0
  • 删除[]名称;并删除名称;导致相同的结果,粉碎:(
  • 在默认构造函数中将name初始化为NULL

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


【解决方案1】:

这段代码有很多问题,但我会列出一些大问题。

  1. 正如其他人所说,您 new char 需要比他们大一号。
  2. 您的默认构造函数应将 name 设置为 nullptr。
  3. 每当您进行分配时,您都会遇到内存处理错误,例如在这一行:drv = d;,因为它调用了默认的 operator=,这在您的情况下是不正确的。这就是三巨头的法则,它松散地指出,当您需要(非平凡的)复制构造函数、复制赋值运算符或析构函数时,您很可能也需要实现其他的。你需要写一个 operator=!

根据现有代码,我希望您的 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 数组和自己管理内存是一个糟糕的坏举动。

【讨论】:

  • 你能帮我修改一下代码吗?我前两天试过。但在静脉中。我必须使用 char* 因为它是一个任务。提前致谢。
  • 我为你写了一个 operator=,我相信你可以根据约翰的回答为你的 char 数组长度添加一个 +1,我相信你可以在构造函数中设置 name=0你自己也是。
【解决方案2】:

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&amp; operator=(const driver &amp;d),以遵循三规则。

类似的更改需要automobile

但是我没有看到内存泄漏,是什么让你认为你有一个?

【讨论】:

  • 第三点是未定义的行为,因此可能导致内存泄漏。
【解决方案3】:

在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 ;

【讨论】:

  • 我认为堆栈内存无法正常清理,因此您可以自行删除这些内存。
  • 在此处添加这些新内容并没有让它看起来更像 Java。
猜你喜欢
  • 1970-01-01
  • 2019-08-12
  • 1970-01-01
  • 1970-01-01
  • 2014-04-03
  • 1970-01-01
  • 2016-07-29
  • 1970-01-01
  • 2017-06-25
相关资源
最近更新 更多