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