问个delete的初级问题

antiMight 2012-11-18 08:14:55
	int *integers = new int[3];
integers[0] = 1;
integers[1] = 2;
integers[2] = 3;
int *a = &integers[0];
int *b = &integers[1];
int *c = &integers[2];
delete integers; //关键是这里
std::cout << integers[2]<<std::endl;

第一个问题,上面注释的那行,我delete[] integers 和 不加[]直接delete,结果是一样的,三个int都被delete了,如何解释?
第二个问题,还是那行,如果改成delete a, 结果和上面一样,而不是只delete了integers[0],如果我写delete b或者delete c, 就会报错,原因何在?
...全文
141 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
antiMight 2012-11-18
  • 打赏
  • 举报
回复
引用 1 楼 breakfisher 的回复:
问题1: 你确信都被释放了?
确实释放了
引用 2 楼 firendlys 的回复:
1.对于基本类型, delete[] 和 delete 其实没有区别..... 其实delete[] 和 delete 的区别只在于 [] 版本会为数组的每一项调用相应的类析构函数, 而 delete则只会为数组第一项调用析构函数(而数组的其他项则不调用析构函数) 对于基本类型来说,没有析构函数这个概念,所以,对于基本类型来说,这两个是没有区别的... ……
应该是这样。 我刚试过用struct代替int,发现结论是一样的。 得到的结论是delete时加不加[]要看有没有写析构函数,如果写了析构函数,又没有加[],就会报错,否则会正常清除内存,但是对于类中new了变量的情况一般都要写析构函数,所以数组都统一delete[]比较好。 对于第二个问题,我比较认同firendlys所说第二种解释,就是堆上分配的block的长度信息保存在了首指针能找到的地方,另外,像我代码例子中从中间delete的做法可能会导致,无法完全清除掉整块内存,有可能也是出于这个考虑才不允许从中间delete。
firendlys 2012-11-18
  • 打赏
  • 举报
回复
1.对于基本类型, delete[] 和 delete 其实没有区别..... 其实delete[] 和 delete 的区别只在于 [] 版本会为数组的每一项调用相应的类析构函数, 而 delete则只会为数组第一项调用析构函数(而数组的其他项则不调用析构函数) 对于基本类型来说,没有析构函数这个概念,所以,对于基本类型来说,这两个是没有区别的... 不过,习惯上, new[] 就应该对应 delete[] .... (这些资料我忘了在哪里看到的了,对不对有待商讨...) 2. 这涉及到内存分配. 先问你一个问题: 为什么 new [] 的时候要指定类型,还要指定数组的大小? 这很简单,原因就是编译器需要知道你申请多少内存... 但是,为什么 delete 和 delete[] 却不需要你指定多少内存? (还有 malloc 也要指定大小, 但 free 却不需要!) 有没有想过这个问题呢?delete是怎么知道他需要释放多少内存的呢? 那么,肯定要有一种机制,令 delete 知道他需要删除多少内存! 最简单的方式,就是在某个地方,放一个值,用来表示申请的内存大小. 那怎么可以根据一个指针就得到这个值的大小呢?(因为 delete 的参数只有一个,就是准备删除的指针) 有两种方式:一种是在某个不知道的地方创建一个表,里面有那个指针,还有申请的数据量,以及类型. 这样在delete的时候,就可以通过查表来知道这个内存大小... 另一种是把这个值放在指针的前面的位置(不放在后面,就是因为指针指向的位置以及其后面的位置都是有效数据).这样delete的时候,就可以直接找到申请的内存的大小了...(话说,debug版本的程序,告诉你数组越界了,也是通过这种方式实现的) 然后,结论很明显了, 假如是第一种方式:a[0]这个指针可以通过查表找到,但a[1]这个指针查表的时候找不到! 如果是第二种方式:a[0] 的前面是有这个内存大小的值的,所以,delete是没有问题. 但 a[1] 的前面呢? 是 a[0] , 这个值不是内存的大小,delete的时候不知道需要delete多少内存!所以,delete失败. (ps:实际上,编译器的处理会比这个复杂得多...)
breakfisher 2012-11-18
  • 打赏
  • 举报
回复
问题1: 你确信都被释放了? 问题2: 在new的时候,系统分配的内存地址是赋给了intergers, 因此内存回收时,也是需要从intergers地址开始的。 a指向的是*a = &integers[0];实际上也等效于 *a = intergers; 所以delete a是与前面等效的。但是delete b和c是会报错的,就是因为new的时候系统内记录的内存地址是与intergers相符合的,与b, c不相符合

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧