关于类对象的delete 与delete[]内存泄露问题


   
  class MyClass
  
{
public:
char x;
MyClass():x(1)
{
};
};

int main(int argc,char** argv)
{
while(1)
{
MyClass *a=new MyClass[10];
delete a;
}
}

为什么上述代码不会产生内存泄露问题? 难道是因为类里面的char都分配到了堆里面而类对象本身并不占空间,没在堆分配空间所以才不至于产生内存泄露吗?

内存管理 C++

faulty 12 years, 2 months ago

内存泄露,C++通常是指new出来的内存没有delete掉。在你的代码里边,new了一块内存,然后马上就delete,自然就没有内存泄露了(呃……其实我也不确定啦,因为你用的是delete,而不是delete[])。

@Miao 在评论里面说的,把x换成指针,在构造函数里new一块内存给它,10秒钟内系统就要卡死。如果没有在析构函数里面delete,自然,就会发生上一段所说的,new出来的内存没有delete掉,内存泄露啰!系统也就由此卡死。

那么x换成指针类型后,析构函数里面也用了delete,是不是就不会发生内存泄露呢?不是的。因为“new MyClass[10]”的时候,MyClass的构造函数调用了10次,而“delete a”的时候,MyClass的析构函数只被调用了1次!因为使用delete,就是告诉编译器,a所指的地方,只有一个MyClass对象!

那有什么办法告诉编译器,a所指是一个MyClass数组,而不是单个对象呢?使用 delete[]。那样,编译器就会知道,a所指的地方,有10个MyClass对象(至于怎么知道的,不在这里讨论),于是针对每个对象调用一次析构函数。也就不会有内存泄露了。

记得用delete配对new,用delete[]配对new[]。事实上,代码里边用delete来配对new[],行为未定义,嗯,是C++标准里面没有定义。也许是因为你比较幸运,程序没有表现出问题~~

补充回答一下楼主的疑问:为什么“使用delete删除基础数据类型的数组也是不会发生泄漏的”?
看下面的代码:

   
  char *c = new char[10];
  
delete c;

在“delete c;”时,我们可以认为程序执行了以下两个动作:
1. 针对被delete对象的类型,调用相应的析构函数。因为这里是基础数据类型char,所以没有任何实质性动作。
2. 回收指针c所指的内存块。这里,c的类型没有起作用。就是说,系统并不会因为c的类型是char而只回收一个字节。系统所做的是,根据c的值,找到对应的内存块的大小,以及其他相关信息,然后回收。这些信息哪里来?调用new、new[]的时候记录下来的。记录在什么地方?这是new、new[]的实现者,或者更底层程序的实现者所要关心的......

需要再次强调的是,楼主没有看到内存泄露的现象,并不表示“使用delete删除基础数据类型的数组”是安全的!

喵娜Kina answered 12 years, 2 months ago

Your Answer