今天刷到一道题目结果出乎意料的ggl所以记录一下
以下涉及到内存管理的代码段中,有错误的是:
int *a=new int(12);
//.....
free(a);
int *ip=static_cast<int*>(malloc(sizeof(int)));
*ip=10;
//.....
delete ip;
double *a=new double[1];
//....
delete a;
int *ip=new int(12);
for(int i=0;i<12;++i){
ip[i]=i;
}
delete []ip;
问题在于第三个选项由于a是一个数组,所以我认为应该使用delete[] a但是结果却是用delete a就可以了。
上网查了一下才知道基本类型数组来说,delete a和delete []a的效果是一样的。如果,a是一个自定义对象的数组,那么只能用delete []a。
原因是:
1、针对简单类型 使用new分配后的不管是数组还是非数组形式内存空间用两种方式均可 如:
int *a = new int[10];
delete a;
delete [] a;
此种情况中的释放效果相同 原因在于分配简单类型内存时,内存大小已经确定,系统可以记忆并且进行管理,在析构时,系统并不会调用析构函数,
它直接通过指针可以获取实际分配的内存空间,哪怕是一个数组内存空间(在分配过程中 系统会记录分配内存的大小等信息,此信息保存在结构体_CrtMemBlockHeader中。
2、针对类Class,两种方式体现出具体差异
当你通过下列方式分配一个类对象数组:
class A
{
private:
char *m_cBuffer;
int m_nLen;
public:
A(){ m_cBuffer = new char[m_nLen]; }
~A() { delete [] m_cBuffer; }
};
A *a = new A[10];
delete a; //仅释放了a指针指向的全部内存空间 但是只调用了a[0]对象的析构函数 剩下的从a[1]到a[9]这9个用户自行分配的m_cBuffer对应内存空间将不能释放
从而造成内存泄漏
delete [] a; //释放了a指针指向的全部内存空间 并且调用使用类对象的析构函数释放用户自己分配内存空间
在 vc 中对于简单数据类型int,char等的数组使用delete还是delete[]是完全一样的,不过对于类的实例的数组来说就必须使用delete[],否则可能会引起该类的析沟函数不会被正确调用。