VC中:new的过程中会为申请的内存标记内存头信息(里面纪录了分配内存信息),delete会根据这个信息来释放内存。所以对基本类型,两个delete都一样的
delete
与
delete[]
需要注意的地方
1
:
首先来说一个大家容易忽略的问题:
定义:
int *p=new int;
这个大家一看就知道,在内存中分配了一个
int
类型的空间,没错。但是我想说的是,操作系统在堆在分配
了一个
int
类型空间给
p
指向的空间,但是
p
本身的值是在栈上,我觉的明白这个很重要。比如,你需要
处理一个海量数据,这个数据需要用二维数组来表示,你如果这样定义
int *ptr[MaxNum]
,然后再循环为
每个
ptr[0~MaxNum-1]
分配空间,
这个时候容易隐含一个错误,
我们知道内存中栈的大小大约就
2M
左右,
而堆很大,几乎没有限制,当你的
MaxNum
很大的时候,就会导致内存溢出,因为
ptr
这个值的本身是在
栈上的,而栈的大小就
2M
左右,而你又有这么多个地址要存放,所以会出错。解决办法有二个:一:用
一维数据代替二维数组;二:定义一个二维指针;
然后再动态分配。
2
:
delete
与
delete[]
执行遇到的问题
:
①
int
*p=new int[100];
int
num[100];
p=num;
delete []p;
大家能看出这段代码有什么问题吗?如果你还没看出,那么你对指针及内存的动态分配与释放还需要再学
习。
错误是发生在
delete []p,
为什么呢?按理说用
new[]
申请,用
delete[]
释放,应该没有问题啊。但是错误发
生的原因是因为
delete[]p
释放的是数组
num[100]
的空间,而我们申请的空间根本就没有释放,为什么会
出现这种情况呢?因为此时的指针已指向了
num
数组的首地址,而
num[100]
的空间会由系统自动释放,
而我们现在强行释放,所以会发生错误。
②
int *p=new int[3];
*p=1;
p++;//p
的指向改变了,指向了下一空间
*p=2;
delete []p;
大家能发现这段代码有什么问题吗?
错误还是发生在
delete[]p
,
c/c++
规定,当删除一个指针时,这个指针应指向其首地址,而上面的代码中
p
值已经发生了变化,所以会发生错误,如何避免呢?可以备份一份;如
int * pbak=p
;在释放的时候,用
delete[]pbak
即可。
③
int* p = new int(10);
int *pp=p;
delete []p;
delete []pp;
这段代码哪里又发生了错误呢?
我们要知道,
p
向操作系统申请了
10
个
int
类型的空间,
而
pp
只是指向这个空间,
操作系统并没有为其再
分配
10
个
int
类型的空间,所以当你用
delete[]p
释放这个空间后,再用
delete[]pp
释放就会发生错误。其
实不管用哪个释放,只要释放一次就行了。
④
int a=100;
itn *p=&a;
delete p;
看到了这里,如果你还不能看出这段代码的错误,那你前面的白看了,说明你还是没有真正懂得啊!
错误还是发生在
delete p,
什么原因?因为
p
并没有通过
new
获得内存空间,
只是指向某个变量,
而
delete
p
是强行释放
a
的空间,肯定发生错误啦。
3.
delete
与
delete[]
的区别
我们首先要知道当
delete
的时候,系统会自动调用已分配的对象的析构函数。
那么当我们用
new[]
分配的对象是基本数据类型的时候,用
delete
和
delete[]
没什么区别,都可以。但是当
用
new[]
分配的对象是自定义类型的时候,
必须要用
delete[],
这样它才会调用每个对象的析构函数,
除非你
的析构函数没有做任何事。
总结一句话:使用
new
得来的空间,用
delete
来释放;使用
new []
得来的空间,必须用
delete []
来
释放。这样肯定不会错。