這篇文章主要講解了“C++常見(jiàn)的內(nèi)存泄漏有哪些”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“C++常見(jiàn)的內(nèi)存泄漏有哪些”吧!
讓客戶(hù)滿(mǎn)意是我們工作的目標(biāo),不斷超越客戶(hù)的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶(hù),將通過(guò)不懈努力成為客戶(hù)在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:空間域名、虛擬空間、營(yíng)銷(xiāo)軟件、網(wǎng)站建設(shè)、阿克塞哈薩克族自治網(wǎng)站維護(hù)、網(wǎng)站推廣。
1. C++或者C 中沒(méi)有調(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ì)無(wú)法調(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.沒(méi)有將基類(lèi)析構(gòu)函數(shù)寫(xiě)成virtual 類(lèi)型 也會(huì)導(dǎo)致 內(nèi)存泄漏
野指針
1.指針初始化沒(méi)賦值
2. 指針delete后沒(méi)有置空 NULL 使得指針指向垃圾內(nèi)存
3.指針操作超過(guò)自己該有的權(quán)限 越權(quán) 段錯(cuò)誤
1. 在類(lèi)的構(gòu)造函數(shù)和析構(gòu)函數(shù)中沒(méi)有匹配的調(diào)用new和delete函數(shù)
兩種情況下會(huì)出現(xiàn)這種內(nèi)存泄露:一是在堆里創(chuàng)建了對(duì)象占用了內(nèi)存,但是沒(méi)有顯示地釋放對(duì)象占用的內(nèi)存;二是在類(lèi)的構(gòu)造函數(shù)中動(dòng)態(tài)的分配了內(nèi)存,但是在析構(gòu)函數(shù)中沒(méi)有釋放內(nèi)存或者沒(méi)有正確的釋放內(nèi)存
2. 沒(méi)有正確地清除嵌套的對(duì)象指針
3. 在釋放對(duì)象數(shù)組時(shí)在delete中沒(méi)有使用方括號(hào)
方括號(hào)是告訴編譯器這個(gè)指針指向的是一個(gè)對(duì)象數(shù)組,同時(shí)也告訴編譯器正確的對(duì)象地址值病調(diào)用對(duì)象的析構(gòu)函數(shù),如果沒(méi)有方括號(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)用無(wú)效對(duì)象(內(nèi)存溢出)的析構(gòu)函數(shù),會(huì)造成堆的奔潰。如果方括號(hào)中間的數(shù)字值比對(duì)象數(shù)組的大小小的話(huà),編譯器就不能調(diào)用足夠多個(gè)析構(gòu)函數(shù),結(jié)果會(huì)造成內(nèi)存泄露。
釋放單個(gè)對(duì)象、單個(gè)基本數(shù)據(jù)類(lèi)型的變量或者是基本數(shù)據(jù)類(lèi)型的數(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è)指針,但是并沒(méi)有釋放對(duì)象的空間,正確的做法,是通過(guò)一個(gè)循環(huán),將每個(gè)對(duì)象釋放了,然后再把指針釋放了
5. 缺少拷貝構(gòu)造函數(shù)
兩次釋放相同的內(nèi)存是一種錯(cuò)誤的做法,同時(shí)可能會(huì)造成堆的奔潰。
按值傳遞會(huì)調(diào)用(拷貝)構(gòu)造函數(shù),引用傳遞不會(huì)調(diào)用。
在C++中,如果沒(méi)有定義拷貝構(gòu)造函數(shù),那么編譯器就會(huì)調(diào)用默認(rèn)的拷貝構(gòu)造函數(shù),會(huì)逐個(gè)成員拷貝的方式來(lái)復(fù)制數(shù)據(jù)成員,如果是以逐個(gè)成員拷貝的方式來(lái)復(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è)類(lèi)里面有指針成員變量,要么必須顯示的寫(xiě)拷貝構(gòu)造函數(shù)和重載賦值運(yùn)算符,要么禁用拷貝構(gòu)造函數(shù)和重載賦值運(yùn)算符
6. 缺少重載賦值運(yùn)算符
這種問(wèn)題跟上述問(wèn)題類(lèi)似,也是逐個(gè)成員拷貝的方式復(fù)制對(duì)象,如果這個(gè)類(lèi)的大小是可變的,那么結(jié)果就是造成內(nèi)存泄露,如下圖:
7. 關(guān)于nonmodifying運(yùn)算符重載的常見(jià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)存泄露,并且無(wú)法回收
解決這一類(lèi)問(wèn)題的辦法是重載運(yùn)算符函數(shù)的返回值不是類(lèi)型的引用,二應(yīng)該是類(lèi)型的返回值,即不是 int&而是int
8. 沒(méi)有將基類(lèi)的析構(gòu)函數(shù)定義為虛函數(shù)
當(dāng)基類(lèi)指針指向子類(lèi)對(duì)象時(shí),如果基類(lèi)的析構(gòu)函數(shù)不是virtual,那么子類(lèi)的析構(gòu)函數(shù)將不會(huì)被調(diào)用,子類(lèi)的資源沒(méi)有正確是釋放,因此造成內(nèi)存泄露
野指針:指向被釋放的或者訪(fǎng)問(wèn)受限內(nèi)存的指針。
造成野指針的原因:
指針變量沒(méi)有被初始化(如果值不定,可以初始化為NULL)
指針被free或者delete后,沒(méi)有置為NULL, free和delete只是把指針?biāo)赶虻膬?nèi)存給釋放掉,并沒(méi)有把指針本身干掉,此時(shí)指針指向的是“垃圾”內(nèi)存。釋放后的指針應(yīng)該被置為NULL.
指針操作超越了變量的作用范圍,比如返回指向棧內(nèi)存的指針就是野指針。
感謝各位的閱讀,以上就是“C++常見(jiàn)的內(nèi)存泄漏有哪些”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)C++常見(jiàn)的內(nèi)存泄漏有哪些這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!