C++:派生 class 对象被破坏时释放动态内存
C++: Deallocating dynamic memory when derived class object is destructed
我似乎对动态内存分配有疑问。
下面您将看到一个派生的 class,它包含一个指向将使用 void name(const char* name)
方法动态分配的名称变量的指针。 Product 构造函数是 运行 的函数,它在创建对象时为产品设置名称 class。这是 class:
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;
}
对我来说,这段代码似乎足以创建对象,然后在它退出它所在的函数范围时和平地销毁它 运行。但是,当函数结束并且析构函数 运行s,程序 freezes/crashes 在 delete [] name_
。 运行 Visual Studio 编译器上的程序似乎没有产生特别的错误(除了程序冻结),但 gcc 编译器检测到某种堆损坏。有人知道为什么会这样吗?
我不确定为什么 Sean Cline 没有 post 他的评论作为答案,但 Sean 是正确的。
name_
给出 g
个元素,然后 name_[g]
设置为零,但 name_[g]
是数组末尾的一个。使用 name_ = new char[g+1];
或 name_[g-1] = 0;
这样你就不会越过数组的末尾。
此外,正如一些评论所指出的,任何时候你有一个动态分配内存的class,确保你定义了复制构造函数,赋值运算符,以及析构函数。如果您错过了一个,默认实现将执行 浅拷贝,这会让您头疼。
A 浅拷贝是指针被拷贝而不是它指向的数据。在你的例子中,如果这个 class 的一个对象被复制或分配,你最终会得到两个指向堆上相同数据的对象,并且它们都会在 运行 时尝试删除它他们的析构函数。
有关这些函数的详细信息,请参阅 Rule of Three
我似乎对动态内存分配有疑问。
下面您将看到一个派生的 class,它包含一个指向将使用 void name(const char* name)
方法动态分配的名称变量的指针。 Product 构造函数是 运行 的函数,它在创建对象时为产品设置名称 class。这是 class:
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;
}
对我来说,这段代码似乎足以创建对象,然后在它退出它所在的函数范围时和平地销毁它 运行。但是,当函数结束并且析构函数 运行s,程序 freezes/crashes 在 delete [] name_
。 运行 Visual Studio 编译器上的程序似乎没有产生特别的错误(除了程序冻结),但 gcc 编译器检测到某种堆损坏。有人知道为什么会这样吗?
我不确定为什么 Sean Cline 没有 post 他的评论作为答案,但 Sean 是正确的。
name_
给出 g
个元素,然后 name_[g]
设置为零,但 name_[g]
是数组末尾的一个。使用 name_ = new char[g+1];
或 name_[g-1] = 0;
这样你就不会越过数组的末尾。
此外,正如一些评论所指出的,任何时候你有一个动态分配内存的class,确保你定义了复制构造函数,赋值运算符,以及析构函数。如果您错过了一个,默认实现将执行 浅拷贝,这会让您头疼。
A 浅拷贝是指针被拷贝而不是它指向的数据。在你的例子中,如果这个 class 的一个对象被复制或分配,你最终会得到两个指向堆上相同数据的对象,并且它们都会在 运行 时尝试删除它他们的析构函数。
有关这些函数的详细信息,请参阅 Rule of Three