在此羅列一些可能導致段錯誤的地方,以及如何避免相應的錯誤
出現段錯誤時,有的很容易調查,但有的很難調查,比如在乙個地方把記憶體寫錯,需要過一段時間另乙個地方讀這個記憶體時,才出錯。這種是非常難定位的。因此在編寫**時一定要小心預防。
1 使用非法的指標,包括使用未經初始化及已經釋放的指標(指標使用之前和釋放之後置為null)
2 記憶體讀/寫越界。包括陣列訪問越界,或在使用一些寫記憶體的函式時,長度指定不正確或者這些函式本身不能指定長度,典型的函式有strcpy(strncpy),sprintf(snprint)等等。
3 對於c++物件,請通過相應類的介面來去記憶體進行操作,禁止通過其返回的指針對記憶體進行寫操作,典型的如string類的data()和c_str()兩個介面。
4 函式不要返回其中區域性物件的引用或位址,當函式返回時,函式棧彈出,區域性物件的位址將失效,改寫或讀這些位址都會造成未知的後果。
5 避免在棧中定義過大的陣列,否則可能導致程序的棧空間不足,此時也會出現段錯誤。
6 作業系統的相關限制,如:程序可以分配的最大記憶體,程序可以開啟的最大檔案描述符個數等,這些需要通過ulimit或setrlimit或sysctl來解除相關的限制。
7 多執行緒的程式,涉及到多個執行緒同時操作一塊記憶體時必須進行互斥,否則記憶體中的記憶體將不可預料
8 使用非執行緒安全的函式呼叫
9 在有訊號的環境中,使用不可重入函式呼叫,而這些函式內部會讀或寫某片記憶體區,當訊號中斷時,記憶體寫操作將被打斷,而下次進入時將不避免的出錯。
10 跨程序傳遞某個位址
11 某些有特殊要求的系統呼叫,例如epool_wait,正常情況下使用close關閉乙個套接字後,epool會不再返回這個socket上的事件,但是如果你使用dup或dup2操作,將導致epool無法進行移除操作。
出現段錯誤的情況彙總
1.訪問陣列時超過陣列邊界 int data 20 int n for n 0 n 20 n 上面宣告的陣列長度為20,但是卻會訪問data 20 已經超過了陣列邊界,導致段錯誤出現。2.陣列的長度是負值 int imgwidth,imgheight long long len imgwidth i...
執行緒可能導致記憶體洩露的情況
繼承thread的執行緒,在交給jdk1.4並發包的執行緒池執行完畢後並沒有被釋放資源,而且也沒被再利用,而是白白佔著記憶體,導致記憶體洩露。預設的thread本身初始化在1.4是將自己加入了乙個threadgroup,如果你沒有呼叫它的start方法,jvm不會在該執行緒結束後將這個thread從...
Linux共享記憶體之段錯誤
最近為了學習作業系統,練習寫乙個shell,然後其中採用了共享記憶體的方案。然而在共享記憶體初始化的時候移植了之前寫共享記憶體實驗已經成功的初始化 卻出現了段錯誤。主要 如下 include stupidshell.h int loop int shm id char shm buff cmdpoo...