繁体   English   中英

C ++:在派生类对象被破坏时释放动态内存

[英]C++: Deallocating dynamic memory when derived class object is destructed

我似乎有动态内存分配的问题。

下面你将看到一个派生类,它包含一个名称变量的指针,该变量将使用void name(const char* name)方法动态分配。 该函数由Product构造函数运行,该构造函数在创建对象时为产品类设置名称。 这是班级:

namespace sict {
  class Product :public Streamable {

    char* name_;

public:

    Product(const char* name);
    virtual ~Product();

    void name(const char* name);

}

这里是名称函数本身,以及一个参数构造函数:

void sict::Product::name(const char * name) {
    int g = strlen(name);
    name_ = new char[g];
    strncpy(name_, name, g);
    name_[g] = 0;
}

Product::~Product() {
    delete [] name_;
    name_ = nullptr;
}

对我来说,这个代码似乎能够创建对象,然后在它退出运行它的函数范围时安静地销毁它。但是,当函数结束并且析构函数运行时,程序在delete [] name_冻结/崩溃。 在Visual Studio的编译器上运行该程序似乎没有产生任何特定错误(程序冻结除外),但gcc编译器检测到某种堆损坏。 有人会知道为什么会这样吗?

我不确定为什么Sean Cline没有发表他的评论作为答案,但肖恩是正确的。

name_被赋予g元素,然后name_[g]被设置为零,但name_[g]是一个超过数组末尾的元素。 使用name_ = new char[g+1]; name_[g-1] = 0; 这样你就不会超过数组的末尾。

此外,正如几条评论所指出的那样,每当你有一个动态分配内存的类时,请确保定义了复制构造函数赋值运算符析构函数 如果您错过了一个,默认实现将执行浅拷贝 ,这可能会让您头疼。

浅拷贝是指复制指针而不是指向的数据。 在您的情况下,如果复制或分配此类的对象,最终会有两个指向堆上相同数据的对象,并且它们都会在运行析构函数时尝试删除它。

有关这些功能的更多信息,请参阅“三规则”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM