段错误、内存泄漏、内存溢出、堆溢出、栈溢出
參考:內(nèi)存泄漏、內(nèi)存溢出、段錯(cuò)誤、堆溢出、棧溢出
作者:焦木白
發(fā)布時(shí)間:2019-10-22
網(wǎng)址:https://blog.csdn.net/jiaomubai/article/details/102680705?spm=1001.2014.3001.5501
目錄
- 段錯(cuò)誤
- 內(nèi)存泄漏
- 內(nèi)存溢出
- 棧溢出
- 堆溢出
段錯(cuò)誤
什么時(shí)候會(huì)發(fā)生段錯(cuò)誤?
段錯(cuò)誤通常發(fā)生在訪問(wèn)非法內(nèi)存地址的時(shí)候,即使用了野指針(指向一個(gè)已刪除的對(duì)象或者未申請(qǐng)?jiān)L問(wèn)受限內(nèi)存區(qū)域的指針)或這試圖修改字符串常量的內(nèi)容。
內(nèi)存泄漏
內(nèi)存泄漏(memory leak)是指由于疏忽或錯(cuò)誤造成了程序未能釋放掉不再使用的內(nèi)存的情況。內(nèi)存泄漏并非指內(nèi)存在物理意義上的消失,而是應(yīng)用程序分配某段內(nèi)存后,由于設(shè)計(jì)錯(cuò)誤,失去了對(duì)該段內(nèi)存的控制,因而造成了內(nèi)存的浪費(fèi)。
內(nèi)存泄漏的分類:
(1)堆內(nèi)存泄漏(heap leak):堆內(nèi)存指的是程序在運(yùn)行中根據(jù)通過(guò)malloc/new等從堆中分配的一塊內(nèi)存,使用完成后必須通過(guò)調(diào)用相對(duì)應(yīng)的free/delete釋放掉。如果程序設(shè)計(jì)的錯(cuò)誤導(dǎo)致這部分內(nèi)存沒(méi)有被釋放掉,那么此后這塊內(nèi)存將不會(huì)被使用,就會(huì)產(chǎn)生堆內(nèi)存泄漏。
(2)系統(tǒng)資源泄漏(resource leak):主要指程序使用系統(tǒng)分配的資源比如bitmap、handle、socket等沒(méi)有使用相應(yīng)的函數(shù)釋放掉,導(dǎo)致系統(tǒng)資源的浪費(fèi),嚴(yán)重時(shí)可導(dǎo)致系統(tǒng)性能降低,運(yùn)行不穩(wěn)定。
(3)沒(méi)有將基類的析構(gòu)函數(shù)定義為虛函數(shù)。當(dāng)基類指針指向派生類的對(duì)象時(shí),如果基類的析構(gòu)函數(shù)不是虛函數(shù),那么子類的析構(gòu)函數(shù)將不會(huì)被調(diào)用,子類的資源沒(méi)有被正確釋放掉,因此造成內(nèi)存泄漏。
如何判斷內(nèi)存泄漏?
內(nèi)存泄漏通常是由于調(diào)用了malloc/new等申請(qǐng)內(nèi)存的操作,但是缺少了對(duì)應(yīng)的free/delete操作。為了判斷內(nèi)存泄漏,我們可以使用linux下的內(nèi)存泄漏檢查工具來(lái)判斷內(nèi)存是否泄漏,除此之外,我們可以在寫(xiě)代碼時(shí)添加內(nèi)存申請(qǐng)和釋放的統(tǒng)計(jì)功能,來(lái)統(tǒng)計(jì)當(dāng)前申請(qǐng)和釋放的內(nèi)存是否一致,從而來(lái)判斷內(nèi)存是否泄漏。
內(nèi)存溢出
內(nèi)存溢出指程序在申請(qǐng)內(nèi)存時(shí),沒(méi)有足夠的內(nèi)存供申請(qǐng)者使用。內(nèi)存溢出就是程序員要申請(qǐng)的內(nèi)存空間超過(guò)了系統(tǒng)實(shí)際能夠分配給你的空間,此時(shí)系統(tǒng)相當(dāng)于沒(méi)法滿足程序員的需求,就會(huì)報(bào)內(nèi)存溢出的錯(cuò)誤。
內(nèi)存溢出原因:
(1)內(nèi)存中加載的數(shù)據(jù)量過(guò)于龐大,如一次性從數(shù)據(jù)庫(kù)取出過(guò)多數(shù)據(jù)。
(2)集合類中有對(duì)對(duì)象的引用,使用后未清空,使得不能回收。
(3)代碼中存在死循環(huán)或循環(huán)產(chǎn)生過(guò)多重復(fù)的對(duì)象實(shí)體。
(4)使用的第三方軟件中的bug
(5)啟動(dòng)參數(shù)內(nèi)存值設(shè)定的過(guò)小
棧溢出
一般通俗來(lái)說(shuō),棧溢出就是由于遞歸或循環(huán)嵌套層次太多造成的。在平時(shí)的編程中,造成棧溢出的現(xiàn)象主要有以下幾種:
(1)局部數(shù)組過(guò)大。當(dāng)函數(shù)內(nèi)部的數(shù)組過(guò)大時(shí),有可能導(dǎo)致棧溢出。
(2)遞歸調(diào)用層次太多。遞歸函數(shù)在運(yùn)行時(shí)會(huì)執(zhí)行壓棧操作,當(dāng)壓棧次數(shù)太多時(shí),也會(huì)導(dǎo)致棧溢出。例如,在解決斐波那契數(shù)列時(shí),采用遞歸法求第1000項(xiàng)的斐波那契數(shù)時(shí),往往會(huì)造成棧溢出。
(3)指針或數(shù)組越界。這種情況最常見(jiàn),例如進(jìn)行字符串拷貝,或處理用戶輸入等等。
針對(duì)以上現(xiàn)象的解決辦法有:一是增大棧空間,二是改用動(dòng)態(tài)分配,使用堆(heap)而不是棧(stack)。
堆溢出
通常來(lái)說(shuō),導(dǎo)致堆溢出的操作是不斷的new 一個(gè)對(duì)象,一直創(chuàng)建新的對(duì)象,但是不銷(xiāo)毀。
總結(jié)
以上是生活随笔為你收集整理的段错误、内存泄漏、内存溢出、堆溢出、栈溢出的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 各类曲线的参数方程_常见曲线的参数方程
- 下一篇: linux中ldd命令查看二进制文件(程