溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C++常見的內(nèi)存泄漏有哪些

發(fā)布時(shí)間:2021-11-29 15:28:39 來源:億速云 閱讀:155 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要講解了“C++常見的內(nèi)存泄漏有哪些”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C++常見的內(nèi)存泄漏有哪些”吧!

1. C++或者C 中沒有調(diào)用匹配的 malloc  free   new  delete 導(dǎo)致內(nèi)存泄漏 這是最根本原因。 構(gòu)造函數(shù)new 了 記得析構(gòu)函數(shù)delete

2. 有時(shí) 申請(qǐng)的是int * p =new int[10]; 釋放時(shí) delete p; 正確的應(yīng)該是delete [] p;  或者存在嵌套new 我們只delete 了最外層的

3. 有時(shí)候系統(tǒng)崩潰了會(huì)無法調(diào)用析構(gòu)函數(shù) 因此導(dǎo)致內(nèi)存泄漏    由此引入了auto_ptr 智能指針 

4.有時(shí)我們new了 內(nèi)存  用到了拷貝構(gòu)造函數(shù)  由于默認(rèn)拷貝構(gòu)造函數(shù)是淺拷貝  在析構(gòu)時(shí)出現(xiàn)了 同一資源的重復(fù)釋放delete  出錯(cuò)   注意 深拷貝

5.沒有將基類析構(gòu)函數(shù)寫成virtual 類型 也會(huì)導(dǎo)致 內(nèi)存泄漏


野指針 

1.指針初始化沒賦值

2. 指針delete后沒有置空 NULL  使得指針指向垃圾內(nèi)存

3.指針操作超過自己該有的權(quán)限 越權(quán) 段錯(cuò)誤


1. 在類的構(gòu)造函數(shù)和析構(gòu)函數(shù)中沒有匹配的調(diào)用new和delete函數(shù)

兩種情況下會(huì)出現(xiàn)這種內(nèi)存泄露:一是在堆里創(chuàng)建了對(duì)象占用了內(nèi)存,但是沒有顯示地釋放對(duì)象占用的內(nèi)存;二是在類的構(gòu)造函數(shù)中動(dòng)態(tài)的分配了內(nèi)存,但是在析構(gòu)函數(shù)中沒有釋放內(nèi)存或者沒有正確的釋放內(nèi)存

2. 沒有正確地清除嵌套的對(duì)象指針

3. 在釋放對(duì)象數(shù)組時(shí)在delete中沒有使用方括號(hào)

方括號(hào)是告訴編譯器這個(gè)指針指向的是一個(gè)對(duì)象數(shù)組,同時(shí)也告訴編譯器正確的對(duì)象地址值病調(diào)用對(duì)象的析構(gòu)函數(shù),如果沒有方括號(hào),那么這個(gè)指針就被默認(rèn)為只指向一個(gè)對(duì)象,對(duì)象數(shù)組中的其他對(duì)象的析構(gòu)函數(shù)就不會(huì)被調(diào)用,結(jié)果造成了內(nèi)存泄露。如果在方括號(hào)中間放了一個(gè)比對(duì)象數(shù)組大小還大的數(shù)字,那么編譯器就會(huì)調(diào)用無效對(duì)象(內(nèi)存溢出)的析構(gòu)函數(shù),會(huì)造成堆的奔潰。如果方括號(hào)中間的數(shù)字值比對(duì)象數(shù)組的大小小的話,編譯器就不能調(diào)用足夠多個(gè)析構(gòu)函數(shù),結(jié)果會(huì)造成內(nèi)存泄露。

釋放單個(gè)對(duì)象、單個(gè)基本數(shù)據(jù)類型的變量或者是基本數(shù)據(jù)類型的數(shù)組不需要大小參數(shù),釋放定義了析構(gòu)函數(shù)的對(duì)象數(shù)組才需要大小參數(shù)。

4. 指向?qū)ο蟮闹羔様?shù)組不等同于對(duì)象數(shù)組

對(duì)象數(shù)組是指:數(shù)組中存放的是對(duì)象,只需要delete []p,即可調(diào)用對(duì)象數(shù)組中的每個(gè)對(duì)象的析構(gòu)函數(shù)釋放空間

指向?qū)ο蟮闹羔様?shù)組是指:數(shù)組中存放的是指向?qū)ο蟮闹羔?,不僅要釋放每個(gè)對(duì)象的空間,還要釋放每個(gè)指針的空間,delete []p只是釋放了每個(gè)指針,但是并沒有釋放對(duì)象的空間,正確的做法,是通過一個(gè)循環(huán),將每個(gè)對(duì)象釋放了,然后再把指針釋放了

5. 缺少拷貝構(gòu)造函數(shù)

兩次釋放相同的內(nèi)存是一種錯(cuò)誤的做法,同時(shí)可能會(huì)造成堆的奔潰。

按值傳遞會(huì)調(diào)用(拷貝)構(gòu)造函數(shù),引用傳遞不會(huì)調(diào)用。

在C++中,如果沒有定義拷貝構(gòu)造函數(shù),那么編譯器就會(huì)調(diào)用默認(rèn)的拷貝構(gòu)造函數(shù),會(huì)逐個(gè)成員拷貝的方式來復(fù)制數(shù)據(jù)成員,如果是以逐個(gè)成員拷貝的方式來復(fù)制指針被定義為將一個(gè)變量的地址賦給另一個(gè)變量。這種隱式的指針復(fù)制結(jié)果就是兩個(gè)對(duì)象擁有指向同一個(gè)動(dòng)態(tài)分配的內(nèi)存空間的指針。當(dāng)釋放第一個(gè)對(duì)象的時(shí)候,它的析構(gòu)函數(shù)就會(huì)釋放與該對(duì)象有關(guān)的動(dòng)態(tài)分配的內(nèi)存空間。而釋放第二個(gè)對(duì)象的時(shí)候,它的析構(gòu)函數(shù)會(huì)釋放相同的內(nèi)存,這樣是錯(cuò)誤的。

所以,如果一個(gè)類里面有指針成員變量,要么必須顯示的寫拷貝構(gòu)造函數(shù)和重載賦值運(yùn)算符,要么禁用拷貝構(gòu)造函數(shù)和重載賦值運(yùn)算符

6. 缺少重載賦值運(yùn)算符

這種問題跟上述問題類似,也是逐個(gè)成員拷貝的方式復(fù)制對(duì)象,如果這個(gè)類的大小是可變的,那么結(jié)果就是造成內(nèi)存泄露,如下圖:

C++常見的內(nèi)存泄漏有哪些


7. 關(guān)于nonmodifying運(yùn)算符重載的常見迷思

a. 返回棧上對(duì)象的引用或者指針(也即返回局部對(duì)象的引用或者指針)。導(dǎo)致最后返回的是一個(gè)空引用或者空指針,因此變成野指針

b. 返回內(nèi)部靜態(tài)對(duì)象的引用。

c. 返回一個(gè)泄露內(nèi)存的動(dòng)態(tài)分配的對(duì)象。導(dǎo)致內(nèi)存泄露,并且無法回收

解決這一類問題的辦法是重載運(yùn)算符函數(shù)的返回值不是類型的引用,二應(yīng)該是類型的返回值,即不是 int&而是int

8. 沒有將基類的析構(gòu)函數(shù)定義為虛函數(shù)

當(dāng)基類指針指向子類對(duì)象時(shí),如果基類的析構(gòu)函數(shù)不是virtual,那么子類的析構(gòu)函數(shù)將不會(huì)被調(diào)用,子類的資源沒有正確是釋放,因此造成內(nèi)存泄露


野指針:指向被釋放的或者訪問受限內(nèi)存的指針。

造成野指針的原因:

  1. 指針變量沒有被初始化(如果值不定,可以初始化為NULL)

  2. 指針被free或者delete后,沒有置為NULL, free和delete只是把指針?biāo)赶虻膬?nèi)存給釋放掉,并沒有把指針本身干掉,此時(shí)指針指向的是“垃圾”內(nèi)存。釋放后的指針應(yīng)該被置為NULL.

  3. 指針操作超越了變量的作用范圍,比如返回指向棧內(nèi)存的指針就是野指針。

感謝各位的閱讀,以上就是“C++常見的內(nèi)存泄漏有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)C++常見的內(nèi)存泄漏有哪些這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI