哪里建网站性价比高,国内优秀企业网站欣赏,济南百度整站seo推广,网店推广目录一、对new [] delete [] 的理解1、delete的[]遗漏会带来什么影响二、以示例探讨三、cookie的理解一、对new [] delete [] 的理解
new的对象是个array类型的。
Complex* pca new Complex[3];
//唤起三次ctor
//无法借由参数给予初值
...
delete[] pca; //唤起3次dtor如下…
目录一、对new [] delete [] 的理解1、delete的[]遗漏会带来什么影响二、以示例探讨三、cookie的理解一、对new [] delete [] 的理解
new的对象是个array类型的。
Complex* pca new Complex[3];
//唤起三次ctor
//无法借由参数给予初值
...
delete[] pca; //唤起3次dtor如下图new出来的是一个array大小为3. new的时候要调用3次ctordelete的时候需要调用3次dtor。分配一个array的时候会顺带分配一个cookie用来记录信息最主要的就是array的长度了。
1、delete的[]遗漏会带来什么影响
如果delete后面不加[]编译器会以为只需要delete所指的对象所以只会调用一次dtor然而cookie记录中的array长度并没有改变此时就会少还一些内存给操作系统从而导致内存泄漏。 str1、str2、str3会被完整回收但是在回收之前需要调用析构函数。由于string在构造上会带有一个指针指针指向真正的字符串的内存空间。调用三次dtor会被很干净地清掉。而少加了[]会就只调用一次dtor导致三块只释放掉了一块。 注意泄露的内存不是str1 2 3,而是指向的真正的字符串的内存空间。 **如果这里的array里面的元素类型是复数Complex就不会造成内存泄漏因为复数里面不包含指针。所以调用三次和调用一次也就无所谓了。**不过为了统一还是要加上[]。
二、以示例探讨
示例代码 A有一个默认构造函数因为我们在new一个数组的时候不能一一地给定值我们new是时候会调用三次构造函数。 构造函数和析构函数会在屏幕上输出占用内存位置
class A
{
public:int id;A() : id(0) { cout default ctor. this this id id endl; }A(int i) : id(i) { cout ctor. this this id id endl; }~A() { cout dtor. this this id id endl; }
};A* buf new A[size]; //default ctor 3 次. [0]先於[1]先於[2])//A必須有 default ctor, 否則 [Error] no matching function for call to jj02::A::A()A* tmp buf; cout buf buf tmp tmp endl; for(int i 0; i size; i)new (tmp) A(i); //3次 ctor cout buf buf tmp tmp endl;delete [] buf; //dtor three times (次序逆反, [2]先於[1]先於[0]) 执行结果 1、默认构造函数默认id 0 2、this指针会自动移动间距是一个对象的大小(int 4个字节) 3、移动指针设初值调用有参构造函数 4、需要注意这样的语法new(指针指向已经分配的内存我们在指针所指的地方进行设置初值) A(i),这属于placement new 的用法之后的笔记会详细讲到。 5、循环过后id被修改地址没有被修改 6、最后delete[],观察可知调用了3次析构函数析构的次序与构造的次序相反。不同的编译环境析构次序可能不同
三、cookie的理解
在做内存管理的时候会有一个很大的诉求就是不要这个cookie所以cookie的存在以及大小是我们需要理解度的。 下面是VC6中观察malloc给我们的内存布局而我们获得的值指向分配的10个int数据的起始地址*pi.可以看到除了我们认定的需要的10个int外malloc还会分配32bytes和4bytes橙色部分。另外还有上cookie和下cookie负责记录整块的大小。 另外还有一个pad区域这是由于在VC6下malloc分配的内存必须是16bytes的倍数如果不是则需要填充额外内存使之为16bytes的倍数。 注意cookie记录的分配的内存大小为60h不过最后一个bit要被用做on or off 的状态的切换所以为61h。(存疑不是很理解这句话之后再补上理解。)上下cookie的数值一样。 这里的delete加不加[]是没有影响的。 如果这里我们不是存放的int类型的数据而是放的是一个对象并且它的析构函数是有意义的此时编译器创造array的方式会有所不同。 注意每个demo对象中存放的是三个int我们new了3个demo分配的内存与之前相比多了一个3即3个demo。 delete不加[],编译器将p当做普通指针指向一块对象然后以一块对象的方式去解释布局但是此刻的布局与之前不同多了一个3所以解释会发生错误。 使用array new和array delete时内存块分配是不一样的。array元素个数被写到内存块里去了。 60h内存计算方式: 60h 32debugger header 4(3:元素个数int类型4个bytes) 3 x 12 (3个 demo object) 4 (no man land) 12(pad) 4 x 2上喜下两个cookie 96个byte 60h个byte(pad是会变动的)