C++ 内存基本构件new [] /delete []的意义、内存泄漏原因、VC下cookie的基本布局
目錄
- 一、對new [] delete [] 的理解
- 1、delete的[]遺漏會帶來什么影響
- 二、以示例探討
- 三、cookie的理解
一、對new [] delete [] 的理解
new的對象是個array類型的。
Complex* pca = new Complex[3]; //喚起三次ctor //無法借由參數(shù)給予初值 ... delete[] pca; //喚起3次dtor如下圖,new出來的是一個array,大小為3.
new的時候要調(diào)用3次ctor,delete的時候需要調(diào)用3次dtor。分配一個array的時候,會順帶分配一個cookie,用來記錄信息,最主要的就是array的長度了。
1、delete的[]遺漏會帶來什么影響
如果delete后面不加[],編譯器會以為只需要delete所指的對象,所以只會調(diào)用一次dtor,然而cookie記錄中的array長度并沒有改變,此時就會少還一些內(nèi)存給操作系統(tǒng),從而導(dǎo)致內(nèi)存泄漏。
str1、str2、str3會被完整回收,但是在回收之前需要調(diào)用析構(gòu)函數(shù)。由于string在構(gòu)造上會帶有一個指針,指針指向真正的字符串的內(nèi)存空間。調(diào)用三次dtor,會被很干凈地清掉。而少加了[],會就只調(diào)用一次dtor,導(dǎo)致三塊只釋放掉了一塊。
注意泄露的內(nèi)存不是str1 2 3,而是指向的真正的字符串的內(nèi)存空間。
**如果這里的array里面的元素類型是復(fù)數(shù)Complex,就不會造成內(nèi)存泄漏,因為復(fù)數(shù)里面不包含指針。所以調(diào)用三次和調(diào)用一次也就無所謂了。**不過為了統(tǒng)一,還是要加上[]。
二、以示例探討
示例代碼:
A有一個默認(rèn)構(gòu)造函數(shù),因為我們在new一個數(shù)組的時候不能一一地給定值,我們new是時候會調(diào)用三次構(gòu)造函數(shù)。
構(gòu)造函數(shù)和析構(gòu)函數(shù)會在屏幕上輸出占用內(nèi)存位置
執(zhí)行結(jié)果:
1、默認(rèn)構(gòu)造函數(shù),默認(rèn)id= 0 ;
2、this指針會自動移動,間距是一個對象的大小(int 4個字節(jié))
3、移動指針,設(shè)初值,調(diào)用有參構(gòu)造函數(shù)
4、需要注意這樣的語法new(指針,指向已經(jīng)分配的內(nèi)存,我們在指針?biāo)傅牡胤竭M(jìn)行設(shè)置初值) A(i),這屬于placement new 的用法,之后的筆記會詳細(xì)講到。
5、循環(huán)過后id被修改,地址沒有被修改
6、最后delete[],觀察可知,調(diào)用了3次析構(gòu)函數(shù),析構(gòu)的次序與構(gòu)造的次序相反。(不同的編譯環(huán)境析構(gòu)次序可能不同)
三、cookie的理解
在做內(nèi)存管理的時候,會有一個很大的訴求,就是不要這個cookie,所以cookie的存在以及大小是我們需要理解度的。
下面是VC6中,觀察malloc給我們的內(nèi)存布局:而我們獲得的值指向分配的10個int數(shù)據(jù)的起始地址*pi.可以看到,除了我們認(rèn)定的需要的10個int外,malloc還會分配32bytes和4bytes(橙色部分)。另外還有上cookie和下cookie,負(fù)責(zé)記錄整塊的大小。
另外還有一個pad區(qū)域,這是由于在VC6下,malloc分配的內(nèi)存必須是16bytes的倍數(shù),如果不是,則需要填充額外內(nèi)存使之為16bytes的倍數(shù)。
注意cookie記錄的分配的內(nèi)存大小為60h,不過最后一個bit要被用做on or off 的狀態(tài)的切換,所以為61h。(存疑,不是很理解這句話,之后再補上理解。)上下cookie的數(shù)值一樣。
這里的delete加不加[]是沒有影響的。
如果這里我們不是存放的int類型的數(shù)據(jù),而是放的是一個對象,并且它的析構(gòu)函數(shù)是有意義的,此時編譯器創(chuàng)造array的方式會有所不同。
注意每個demo對象中存放的是三個int,我們new了3個demo,分配的內(nèi)存與之前相比多了一個3,即3個demo。
delete不加[],編譯器將p當(dāng)做普通指針,指向一塊對象,然后以一塊對象的方式去解釋布局,但是此刻的布局與之前不同,多了一個3,所以解釋會發(fā)生錯誤。
使用array new和array delete時,內(nèi)存塊分配是不一樣的。array元素個數(shù)被寫到內(nèi)存塊里去了。
60h內(nèi)存計算方式:
60h = 32(debugger header) + 4(3:元素個數(shù),int類型,4個bytes) + 3 x 12 (3個 demo object) + 4 (no man land) +12(pad) + 4 x 2(上喜下兩個cookie)= 96個byte = 60h個byte(pad是會變動的)
總結(jié)
以上是生活随笔為你收集整理的C++ 内存基本构件new [] /delete []的意义、内存泄漏原因、VC下cookie的基本布局的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ 内存基本构件new/delete
- 下一篇: 1080×1920分辨率超过2m吗?