new和delete[]的隐藏属性(new+delete补充)
我们在一次测试中突然发现,用new开辟的内置类型空间数组,我们知道是需要delete[]来进行释放的,但是突然发现不加[],光delete也可以将其释放,不会造成内存泄漏:
查找资料后发现,是因为new开辟内置类型空间的时候会将其开辟的大小信息也存储下来,在delete的时候进行释放,而不会造成内存泄漏。
这不是我们今天的重点,重点是在new开辟对象数组,delete的时候没有加[],那么会自动将其它对象空间释放掉吗?
如果是,那么就很恐怖了,因为我们知道开辟的内置类型变量只是一个内存块,而开辟的对象是内存+资源的存在,如果delete直接将其他对象的内存也直接释放掉,那么对象的析构函数只会调用触发一次,其他的对象的额外资源得不到正常释放。
我们可以看看测试结果:
我们可以看到,类Test的构造函数调用了10次,而析构函数只会调用一次。
那么我们应该思考一下,为什么delete会将其他对象的内存也释放掉,难道它也知道开辟的对象个数吗?
或者这样问:int *p = new Test[10]; 这个Test对象空间是开辟了10个还是11个?
我们经过测试发现,是会多开辟一个对象内存空间在最头部,也就是[-1]的位置。
这个对象内存空间存储了其开辟的对象个数,这个数值保存在对象最小的数据类型变量上(指针除外)。
例如如下类Test最小的成员变量类型是char:
所以不可避免的会存在数值溢出的问题,比如char类型的范围是【-128,+127】,那么开辟128个对象的时候,这个char类型必将会存储不下来:
所以我们会发现,我们会发现[]是真的不能丢,很容易出现内存释放不完全的状况。