使用初始化程序列表的初始化类成员导致内存泄漏

时间:2019-07-15 23:24:36

标签: c++

我有一个类,其中包含属性char *变量名,该名称指向包含C样式文本字符串的new char []分配的char数组。我正在使用具有属性char []变量name_val且等于“ emtpy”的重载构造函数。在成员初始化列表中,我已将私有类成员名称初始化为nullptr,并且在构造函数内部,我为它分配了空间以name_val的大小,使用strcpy将其复制到name。当我编译程序时,我得到警告说: [警告]不建议将字符串常量转换为'char *'[-Wwrite-strings]。我还看到内存泄漏。因此,我花了很少的时间弄乱,并且在将char name_val设置为const char name_val [] =“ empty”时,在重载的构造函数中,一切正常。

这里是代码,请注意,在重载的构造函数中,属性char []变量名name_ val未设置为const!

有人可以解释一下,在这种情况下const的目的是什么?

#include<iostream>
#include<cstring>

using namespace std;

class Person{
    char *name;
public:
    Person(char name_val[]="empty"):
        name{nullptr}{
            name=new char[strlen(name_val)+1];
            strcpy(name,name_val);
        }
    ~Person(){
        delete [] name;name=nullptr;
    }

    char *get_Name()const{return name;}
};

int main(){

    Person p;
    cout<<p.get_Name()<<endl;
    return 0;
}

2 个答案:

答案 0 :(得分:2)

  

使用初始化列表的初始化类成员会导致内存泄漏

     

我也看到内存泄漏。

在所示的程序中没有内存泄漏。目前尚不清楚为什么您会认为自己看到了它。

  

有人可以解释一下,在这种情况下const的目的是什么?

对象为const表示无法修改其状态(在类类型的情况下,可变成员除外)。指向const的指针/引用意味着不能通过指针/引用修改指向/引用的对象。

指向非const的指针可以隐式地转换为指向const的指针,但返回的转换不是隐式的。

字符串文字是常量。从C ++ 11开始,不能将指向非常量(char*)的指针分配为指向const对象。您看到的警告消息表示您正在使用C ++ 11之前的版本。那时,从字符串文字到char*的转换格式良好,但是不建议使用该转换。


P.S。 Person有一个严重的设计缺陷:该类是可复制的,但是如果您有意或无意地进行了复制,则该程序的行为将是不确定的。

P.P.S。默认成员初始化程序是多余的,因为您从不使用它。

答案 1 :(得分:0)

写时:

Person(char name_val[]="empty")

相当于写作:

Person(char *name_val="empty")

,现在您可以看到您正在将字符串常量分配给非常量char *,因此出现了警告。解决方案(显然)是编写:

Person(const char *name_val="empty")

然后编译器会很高兴。

OTOH,写时:

Person()
{
    char name_val[]="empty"
    ...
}

然后您要在堆栈上创建一个字符数组并将给定的字符串常量复制到其中,因此不需要const(尽管在这种情况下仍然是个好主意)。

我不知道您为什么认为自己存在内存泄漏。我在您的代码中看不到。