淺談 C++ 中的Segmentation Fault 錯誤

更新 發佈閱讀 5 分鐘

在工作中遇到的問題實在是千奇百怪,跟C++搏鬥了好一陣子了,仍然還是跟它不是很熟,最近工作上更遇到了bug之王的segmentation fault錯誤,雖然還沒找出root cause,不過在找了一陣子未果後,想說透過更系統性的方法來調查甚麼原因會導致segmentation fault。

何謂 Segmentation fault (記憶體區段錯誤)?

記憶體區段錯誤,也稱存取權限衝突(access violation),它會出現在當程式企圖存取CPU無法定址的記憶體區段時。當錯誤發生時,硬體會通知作業系統產生了記憶體存取權限衝突的狀況。作業系統通常會產生核心轉儲(core dump)以方便開發者進行除錯。

因此,即便當下通過編譯,也有可能在執行程式的期間,由於記憶體位置存取不當而發生這類型的錯誤,錯誤訊息通常為 “Access Violation Writing Location"。

以下Grant整理了幾種會導致Segmentation fault 的情況。

(1)錯誤的訪問寫入至唯讀記憶體

#include<stdio.h> 
#include<stdlib.h>

int main() {
   char *c = "hello world";
   c[1] = 'H';
}

基本上當一個字元指標常量宣告並賦值後,就會被儲存於唯獨記憶體中,而試圖寫入至唯讀記憶體段會引發區段錯誤。因此,為了避免這種狀況,建議在常數前加上const,這樣在編譯階段,編譯器就會報錯了。

raw-image

(2)訪問了不屬於程式地址空間的內存

指標在宣告後,必須指向對應的位址,但對於寫入受保護的位址,是不被允許的。

linux 位址上的頂部的四分之一是保留给內部核心的。即 0xffffffff 到 0xc0000000 是不可存取的地址,而下面的 0xc0000fff 即是在這區間。

#include <stdio.h>   
#include <stdlib.h>

int main() {
  int *p = (int*)0xC0000fff;
  *p = 10;
}

(3)寫入空指標

空指標(0 or NULL)時所指向的記憶體位址是受到保護的,所以一旦遭到強行寫入,都會發生區段錯誤。

#include <stdio.h>  
#include <stdlib.h>
#include <iostream>

int main(){
int *i=0;
  std::cout << &i;
  scanf ("%d", i);
  printf ("%d\n", i);
}
raw-image

(4)越界存取

再來一個常見引起區段錯誤的原因即是越界存取不存在的數組,例如以下的程式碼中,只宣告了長度為10的char,卻要印出c的位於第180000的資料。

#include <stdio.h>  
#include <stdlib.h>
#include <iostream>

int main() {
  char c[10];
  printf("%c", c[180000]);
}
raw-image

以上就是一些關於Segmentation fault的知識,一開始對於這個錯誤毫無頭緒,再做過了一些調查也實際上 replicate issue 的 scenarios 之後,總算有點概念了,如果之後有找到工作上遇到的那個問題的root cause,Grant 會再來這裡更新一下。

C++在管理內存較其他語言來說,彈性相當高,這是個兩面刃,一旦對於內存不熟悉,就很有可能corrupt掉整個系統,因此在寫的時候要更加小心。

————–更新——————

後來發現的 root cause 是由於寫入不存在的記憶體。

舉例來說,就是程式中有個兩個陣列,有一個陣列裡面是存要使用的方法的位置,另一個是類似定義要讀檔的 enum,藉由 enum 陣列與方法陣列的 index 來 mapping對應的使用情境。

但這兩個陣列的的內容不匹配,也就是長度不同。例如第一個陣列長度 11,而第二個長度是 12,所以當程式今天讀到第 12 個位置的時候,沒有找到對應的方法的位址的定義,並且在寫入的時候噴錯,因為根本沒有辦法分配對應的位址給不存在的方法。不過,只要是讀1-11的定義都不會有事,也導致在特定情況時才會報出區段錯誤,解法就是把長度為 11 的陣列增加為 12 並分派對應的方法的 address。

留言
avatar-img
留言分享你的想法!
avatar-img
格蘭特的沙龍
14會員
18內容數
還在為不知道怎麼面試而煩惱嗎? 還在為苦無面試機會而沮喪嗎? 別擔心~讓我們一起面對! 在專題中,我將以自身經驗傳授如何撰寫履歷以及分享面試經驗。
格蘭特的沙龍的其他內容
2023/10/26
嗨!我是格蘭特,歡迎來到軟體工程師面試大哉問! 近二十家公司面試經驗大公開,本篇是系列文的第八篇。 這篇將繼續分享上一篇在遊戲橘子的面試經驗。
Thumbnail
2023/10/26
嗨!我是格蘭特,歡迎來到軟體工程師面試大哉問! 近二十家公司面試經驗大公開,本篇是系列文的第八篇。 這篇將繼續分享上一篇在遊戲橘子的面試經驗。
Thumbnail
2023/07/18
嗨!我是格蘭特,歡迎來到軟體工程師面試大哉問! 近二十家公司面試經驗大公開,本篇是系列文的第七篇。 格蘭特這次要分享的是在遊戲領域中的佼佼者,自產及代理多種知名遊戲的遊戲橘子(Gamania)。 本次機會是由 Headhunter 在 LinkedIn 主動聯繫,職位是資深後端工程師。 由於篇
Thumbnail
2023/07/18
嗨!我是格蘭特,歡迎來到軟體工程師面試大哉問! 近二十家公司面試經驗大公開,本篇是系列文的第七篇。 格蘭特這次要分享的是在遊戲領域中的佼佼者,自產及代理多種知名遊戲的遊戲橘子(Gamania)。 本次機會是由 Headhunter 在 LinkedIn 主動聯繫,職位是資深後端工程師。 由於篇
Thumbnail
2023/04/06
歡迎來到格蘭特的私房好書,本文是專題系列文的第二篇。 因工作上有些事情需要處理,讓這個專題延宕了幾個月,希望大家不要見怪 :D。 今天要與大家一同閱讀的是 Annette Simmons 所著的《你的團隊需要一個會說故事的人》。 作者:Annette Simmons (安奈特.西蒙斯) 出版社:先覺
Thumbnail
2023/04/06
歡迎來到格蘭特的私房好書,本文是專題系列文的第二篇。 因工作上有些事情需要處理,讓這個專題延宕了幾個月,希望大家不要見怪 :D。 今天要與大家一同閱讀的是 Annette Simmons 所著的《你的團隊需要一個會說故事的人》。 作者:Annette Simmons (安奈特.西蒙斯) 出版社:先覺
Thumbnail
看更多
你可能也想看
Thumbnail
覺得黏在額頭上的"條碼瀏海"很阿雜嗎?日本熱銷的「KOIZUMI迷你瀏海梳」,不僅小巧便攜,更能快速加熱造型,無論是齊瀏海、空氣瀏海還是韓系碎蓋髮,都能輕鬆打理!瀏海順了,一整天心情就好了!
Thumbnail
覺得黏在額頭上的"條碼瀏海"很阿雜嗎?日本熱銷的「KOIZUMI迷你瀏海梳」,不僅小巧便攜,更能快速加熱造型,無論是齊瀏海、空氣瀏海還是韓系碎蓋髮,都能輕鬆打理!瀏海順了,一整天心情就好了!
Thumbnail
走完朝聖之路和TMB後,我發現真正能撐住長時間健行的,不只是腳力,而是那些讓生活更舒服的小物。這篇整理了我在TMB實測後覺得超好用的三樣登山神器——防水襪、肥皂袋、速乾毛巾,每一樣都讓旅程更輕鬆!
Thumbnail
走完朝聖之路和TMB後,我發現真正能撐住長時間健行的,不只是腳力,而是那些讓生活更舒服的小物。這篇整理了我在TMB實測後覺得超好用的三樣登山神器——防水襪、肥皂袋、速乾毛巾,每一樣都讓旅程更輕鬆!
Thumbnail
題目敘述 題目會給定一個整數陣列nums,原本裡面包含有整數1到n,但是中間不小心出了差錯,導致有一個數字消失了,而另一個數字重複了。 請找出重複的數字以及消失的數字,並且 以陣列的形式[重複的數字, 消失的數字]返回這兩個數字。 例如: [1,3,3,4] 消失的數字是2,重複的數字是
Thumbnail
題目敘述 題目會給定一個整數陣列nums,原本裡面包含有整數1到n,但是中間不小心出了差錯,導致有一個數字消失了,而另一個數字重複了。 請找出重複的數字以及消失的數字,並且 以陣列的形式[重複的數字, 消失的數字]返回這兩個數字。 例如: [1,3,3,4] 消失的數字是2,重複的數字是
Thumbnail
cs50 第四週課程 Recover 解題思路
Thumbnail
cs50 第四週課程 Recover 解題思路
Thumbnail
在第十三課中,我們將探索 Python 中的異常處理。 當 Python 程式運行時,它可能會遇到錯誤。 這些錯誤稱為異常 (Exceptions),如果未被處理,它們會導致程式終止。
Thumbnail
在第十三課中,我們將探索 Python 中的異常處理。 當 Python 程式運行時,它可能會遇到錯誤。 這些錯誤稱為異常 (Exceptions),如果未被處理,它們會導致程式終止。
Thumbnail
MongoDB 在排序時會將資料全部載入記憶體,之後在記憶體中進行排序,而預設開放給排序的記憶體只有 32 MB,因此在大量資料排序時就會引發該錯誤。
Thumbnail
MongoDB 在排序時會將資料全部載入記憶體,之後在記憶體中進行排序,而預設開放給排序的記憶體只有 32 MB,因此在大量資料排序時就會引發該錯誤。
Thumbnail
在工作中遇到的問題實在是千奇百怪,跟C++搏鬥了好一陣子了,仍然還是跟它不是很熟,最近工作上更遇到了bug之王的segmentation fault錯誤,雖然還沒找出root cause,不過在找了一陣子未果後,想說透過更系統性的方法來調查甚麼原因會導致segmentation fault。
Thumbnail
在工作中遇到的問題實在是千奇百怪,跟C++搏鬥了好一陣子了,仍然還是跟它不是很熟,最近工作上更遇到了bug之王的segmentation fault錯誤,雖然還沒找出root cause,不過在找了一陣子未果後,想說透過更系統性的方法來調查甚麼原因會導致segmentation fault。
Thumbnail
Array 在記憶體中連續分配,而且元素類型是一樣的,長度不變 優點:讀取快,可以使用座標訪問 缺點:新增、刪除慢 記憶體: 📷 範例程式碼: ArrayList 不定長度,在記憶體中連續分配的,元素沒有類型限制,任何元素都是當成object處理,如果是值類型,會有裝箱的操作 優點:讀取快 缺點:
Thumbnail
Array 在記憶體中連續分配,而且元素類型是一樣的,長度不變 優點:讀取快,可以使用座標訪問 缺點:新增、刪除慢 記憶體: 📷 範例程式碼: ArrayList 不定長度,在記憶體中連續分配的,元素沒有類型限制,任何元素都是當成object處理,如果是值類型,會有裝箱的操作 優點:讀取快 缺點:
Thumbnail
C笔记:字符串
Thumbnail
C笔记:字符串
Thumbnail
二維陣列(Two-dimensional array)
Thumbnail
二維陣列(Two-dimensional array)
Thumbnail
一維陣列(One dimension array)
Thumbnail
一維陣列(One dimension array)
Thumbnail
在基礎教學完成後,接下來我們就要來學習檔案處理,不論我們今天要分析哪些數據,都需要將數據存取下來並且利用python去讀取出來才能分析,所以這步驟是我們爬蟲的第一步,必須要好好學習唷!!
Thumbnail
在基礎教學完成後,接下來我們就要來學習檔案處理,不論我們今天要分析哪些數據,都需要將數據存取下來並且利用python去讀取出來才能分析,所以這步驟是我們爬蟲的第一步,必須要好好學習唷!!
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News