c++ 中的delete 跟delete[]
c++ 中的delete 和delete[]
我在学校c++的时候一直不明白,为什么会设计出 delete和delete[]两种操作;
因为大家都知道
1,int *p = new int 是分配一个单元,int *p = new int[100]是分配100个单元,
2,delete p 是删除释放一个单元,delete [] p 是释放 多个单元,具体的数据目是查系统的分配表得到的;
3,那么既然可以查表,为什么不直接让delete 和 delete[]合并为一个操作,具体释放多少查表得到既可以了,
可能是设计师考虑到了什么东西了吧,比如效率等,
但是我想不出来,请大家帮我解释一下
------解决方案--------------------
你问的很好,许多人不知道对于内置类型来说,delete和delete []是一样的,看起来你是知道的
原因如下,事实上new和delete都是两步操作,分配(释放)堆内存和调用构造(析构)函数
对于堆内存的释放,确实不需要做额外的事情,delete和delete []无差别
区别就在于调用析构函数这一步,如果用delete只会调用第一个对象的析构,只有调用delete[]才会调用全部的析构
------解决方案--------------------
1.从反汇编的结果看,两者都是一样的。只不过对于对象数组(非编译器定义的类型),delete[]调用全部的析构函数,而delete只调用一次析构。编译器定义的类型,如int,char,string,byte等都是可以正确释放的。
2.规范化编程为好,delete与new配套,delete[]与new []配套使用。
3.最好是自己定制delete与new,因为可以在里面加入一些条件,比如防止删除null指针、内存缓冲池(防止内存碎片)、按需分配(编译器实际申请的内存会比需要申请的多)。
4.也可以使用宏定义来实现内存申请释放操作,防止删除null指针:
http://www.dewen.org/q/447
------解决方案--------------------
这个问题,C++之父在《C++语言的设计和演化》里的解释就是:效率
malloc/free步骤是交给C和系统去做的,系统不区分单个和数组,你就是想区分也没用,反正这不是C++的事,所以之父对此没什么可折腾的
但是析构多少个元素,系统是不管的,这需要编译器做,这就需要考量了。析构是C++的特点,C没有的。之父需要负责的是做同样的事情时,C++的效率不低于C
毫无疑问,数组总是要多一些信息的,如果都把单个理解为size为1的数组,程序员是方便了,但实现效率上是有累赘的
这点累赘值不值得考虑,那就取决于之父的设计原则和时代背景了
------解决方案--------------------
所谓冲击程序效率是从抽象的角度说的,而且基本没有现实意义,本身堆内存自己就维护了数组大小,C语言的free从诞生第一天起就从没让人传过什么size,各种操作系统的资源分配释放也没见过释放的时候指定大小的,因为分配的时候就维护了大小可以说是行规,谁不这样做谁SB
“程序员来决定是否在代码中增加这个[]”根本就没意义,我之前说了,一个对象数组,你用delete也好,用delete[]也好,其结果都是所有的对象都不能用了,因为堆被整体释放了,留下一堆野指针对象的析构函数不释放,完全没意义。为了一点点的性能,造成内存泄漏的大bug,根本不值,更何况这些泄漏的内存理论上就无法重新利用。程序员根本没有决定权,数组必须用delete[]释放,否则就是错误代码
我在学校c++的时候一直不明白,为什么会设计出 delete和delete[]两种操作;
因为大家都知道
1,int *p = new int 是分配一个单元,int *p = new int[100]是分配100个单元,
2,delete p 是删除释放一个单元,delete [] p 是释放 多个单元,具体的数据目是查系统的分配表得到的;
3,那么既然可以查表,为什么不直接让delete 和 delete[]合并为一个操作,具体释放多少查表得到既可以了,
可能是设计师考虑到了什么东西了吧,比如效率等,
但是我想不出来,请大家帮我解释一下
------解决方案--------------------
你问的很好,许多人不知道对于内置类型来说,delete和delete []是一样的,看起来你是知道的
原因如下,事实上new和delete都是两步操作,分配(释放)堆内存和调用构造(析构)函数
对于堆内存的释放,确实不需要做额外的事情,delete和delete []无差别
区别就在于调用析构函数这一步,如果用delete只会调用第一个对象的析构,只有调用delete[]才会调用全部的析构
------解决方案--------------------
1.从反汇编的结果看,两者都是一样的。只不过对于对象数组(非编译器定义的类型),delete[]调用全部的析构函数,而delete只调用一次析构。编译器定义的类型,如int,char,string,byte等都是可以正确释放的。
2.规范化编程为好,delete与new配套,delete[]与new []配套使用。
3.最好是自己定制delete与new,因为可以在里面加入一些条件,比如防止删除null指针、内存缓冲池(防止内存碎片)、按需分配(编译器实际申请的内存会比需要申请的多)。
4.也可以使用宏定义来实现内存申请释放操作,防止删除null指针:
#ifndef SAFE_DELETE
#define SAFE_DELETE(p)
{if(p != NULL) { delete (p); (p) = NULL; } } //Delete object by New create
#endif
#ifndef SAFE_DELETEA //Delete Arrary
#define SAFE_DELETEA(p) {if(p != NULL) {delete[] (p); (p) = NULL;}}
#endif
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) {if(p != NULL) { (p)->Release(); (p) = NULL; } }
#endif
#ifndef SAFE_FREE
#define SAFE_FREE(p) {if(p != NULL) { free(p); (p) = NULL; } }
#endif
#ifndef SAFE_GLOBAL_FREE
#define SAFE_GLOBAL_FREE(p) {if(p != NULL) { GlobalFree(p); (p) = NULL; }}
#endif
http://www.dewen.org/q/447
------解决方案--------------------
这个问题,C++之父在《C++语言的设计和演化》里的解释就是:效率
malloc/free步骤是交给C和系统去做的,系统不区分单个和数组,你就是想区分也没用,反正这不是C++的事,所以之父对此没什么可折腾的
但是析构多少个元素,系统是不管的,这需要编译器做,这就需要考量了。析构是C++的特点,C没有的。之父需要负责的是做同样的事情时,C++的效率不低于C
毫无疑问,数组总是要多一些信息的,如果都把单个理解为size为1的数组,程序员是方便了,但实现效率上是有累赘的
这点累赘值不值得考虑,那就取决于之父的设计原则和时代背景了
------解决方案--------------------
所谓冲击程序效率是从抽象的角度说的,而且基本没有现实意义,本身堆内存自己就维护了数组大小,C语言的free从诞生第一天起就从没让人传过什么size,各种操作系统的资源分配释放也没见过释放的时候指定大小的,因为分配的时候就维护了大小可以说是行规,谁不这样做谁SB
“程序员来决定是否在代码中增加这个[]”根本就没意义,我之前说了,一个对象数组,你用delete也好,用delete[]也好,其结果都是所有的对象都不能用了,因为堆被整体释放了,留下一堆野指针对象的析构函数不释放,完全没意义。为了一点点的性能,造成内存泄漏的大bug,根本不值,更何况这些泄漏的内存理论上就无法重新利用。程序员根本没有决定权,数组必须用delete[]释放,否则就是错误代码