淺談 C++ 中的Segmentation Fault 錯誤

更新於 2024/11/01閱讀時間約 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,這樣在編譯階段,編譯器就會報錯了。

(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); 
}

(4)越界存取

再來一個常見引起區段錯誤的原因即是越界存取不存在的數組,例如以下的程式碼中,只宣告了長度為10的char,卻要印出c的位於第180000的資料。
#include <stdio.h>  
#include <stdlib.h> 
#include <iostream> 
int main() {      
  char c[10];      
  printf("%c", c[180000]);  
}
以上就是一些關於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
14會員
17內容數
還在為不知道怎麼面試而煩惱嗎? 還在為苦無面試機會而沮喪嗎? 別擔心~讓我們一起面對! 在專題中,我將以自身經驗傳授如何撰寫履歷以及分享面試經驗。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
選擇安樂死的人並非一心求死,而是被無法承受的病痛逼入絕境。面對昂貴的醫療費用和漫長的折磨,安樂死成為了上層階級的特權,窮人卻只能在貧窮與無助中掙扎。當醫療體系將延長生命視為一種經濟效益時,安樂死的普及化顯得遙不可及,甚至淪為富人享有的「終極選擇」。
不用妄想實坪制會造成房價下跌
Thumbnail
“搞定自己 的難度和必要性,遠勝於應付別人。”-蔡康永 “搞定自己”相對於”應付他人”而言,往往涉及到更高層次的難度和更深刻的必要性,這是因為搞定自己,需要個人多方面的實現內在成長,以及情感智慧和生活品質的提升 首先,搞定自己需要更多的自我認識和自我反省,這意味著深入了解自己,包括自我需求、
Thumbnail
你有曾經做過這樣的夢嗎? 夢中的你想擺脫你身後的不論是人或是東西, 你一直跑卻怎麼樣也擺脫不了。 其實追趕你的東西, 正是你的潛意識想要提醒你, 去挖掘和發展那些你平常未曾發現的領域。 你擁有力量強大的才能,只是現在還不夠成熟, 這種情況通常要跳脫舒適圈, 才能激發那個才
Thumbnail
為什麼有些中、英術語很難望文生義,很難從中、英詞彙的表面意思對應起來?這種情況,又該如何記住呢? 本文以「融資」、「融券」為例,為你頗析!
Thumbnail
在繪本的世界裡,無字繪本的起源帶著一種教學的色彩。這些書籍沒有文字,目的在於讓年輕的讀者試圖從圖像中挖掘出隱藏的話語。這類書籍明確提出了一個原則:「讓圖片說話」。最初,這類無字繪本是為那些還未學會閱讀的孩子設計的。許多設計理念普遍認為,既然孩子不會讀文字,那麼他們應該能夠輕易地解讀一系列的圖像。
Thumbnail
人人都有自己的恐懼 如何去面對每一次的恐懼來臨呢? 如果不曾直面也許就難以長出相對的勇氣 / 在長濱僻靜時的自我探索中 聊到過我害怕昆蟲 但夥伴覺得我很勇敢 因為當我們一起在室內遇到小蜘蛛時我的反應 但蜘蛛不是我最怕的 我最怕的是大蟑螂 或者說會飛的、移動速度
Thumbnail
被稱為「離別的一族」的長壽種伊歐夫人,外表從青少年時期便停止生長。某天,梅薩蒂軍進攻族地,伊歐夫人就此死散流離,而少女瑪琪亞因此開始了無止盡的流浪。她在途中撿到一名襁褓中的孤兒。四季流轉,艾瑞爾抽長為少年,瑪琪亞卻依舊是少女模樣,在動盪的時代與心緒裡,他們相處的時光因而逐漸生變,再度面臨漫長的別離…
Thumbnail
前言: 央行在昨天6/13的理監事會議後,宣佈今天6/14上路第6波選擇性信用管制,主要內容有兩點,第1點是「調升存款準備率1碼(0.25%)」第2點是「調降自然人特定地區第2戶購屋貸款最高成數上限為6成」,所謂的「特定地區」就是直轄市六都與新竹縣市。
Thumbnail
文章將搜尋引擎的運作原理分為三個段落進行介紹,並強調網站結合有效的SEO策略對提升曝光度的重要性。
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
選擇安樂死的人並非一心求死,而是被無法承受的病痛逼入絕境。面對昂貴的醫療費用和漫長的折磨,安樂死成為了上層階級的特權,窮人卻只能在貧窮與無助中掙扎。當醫療體系將延長生命視為一種經濟效益時,安樂死的普及化顯得遙不可及,甚至淪為富人享有的「終極選擇」。
不用妄想實坪制會造成房價下跌
Thumbnail
“搞定自己 的難度和必要性,遠勝於應付別人。”-蔡康永 “搞定自己”相對於”應付他人”而言,往往涉及到更高層次的難度和更深刻的必要性,這是因為搞定自己,需要個人多方面的實現內在成長,以及情感智慧和生活品質的提升 首先,搞定自己需要更多的自我認識和自我反省,這意味著深入了解自己,包括自我需求、
Thumbnail
你有曾經做過這樣的夢嗎? 夢中的你想擺脫你身後的不論是人或是東西, 你一直跑卻怎麼樣也擺脫不了。 其實追趕你的東西, 正是你的潛意識想要提醒你, 去挖掘和發展那些你平常未曾發現的領域。 你擁有力量強大的才能,只是現在還不夠成熟, 這種情況通常要跳脫舒適圈, 才能激發那個才
Thumbnail
為什麼有些中、英術語很難望文生義,很難從中、英詞彙的表面意思對應起來?這種情況,又該如何記住呢? 本文以「融資」、「融券」為例,為你頗析!
Thumbnail
在繪本的世界裡,無字繪本的起源帶著一種教學的色彩。這些書籍沒有文字,目的在於讓年輕的讀者試圖從圖像中挖掘出隱藏的話語。這類書籍明確提出了一個原則:「讓圖片說話」。最初,這類無字繪本是為那些還未學會閱讀的孩子設計的。許多設計理念普遍認為,既然孩子不會讀文字,那麼他們應該能夠輕易地解讀一系列的圖像。
Thumbnail
人人都有自己的恐懼 如何去面對每一次的恐懼來臨呢? 如果不曾直面也許就難以長出相對的勇氣 / 在長濱僻靜時的自我探索中 聊到過我害怕昆蟲 但夥伴覺得我很勇敢 因為當我們一起在室內遇到小蜘蛛時我的反應 但蜘蛛不是我最怕的 我最怕的是大蟑螂 或者說會飛的、移動速度
Thumbnail
被稱為「離別的一族」的長壽種伊歐夫人,外表從青少年時期便停止生長。某天,梅薩蒂軍進攻族地,伊歐夫人就此死散流離,而少女瑪琪亞因此開始了無止盡的流浪。她在途中撿到一名襁褓中的孤兒。四季流轉,艾瑞爾抽長為少年,瑪琪亞卻依舊是少女模樣,在動盪的時代與心緒裡,他們相處的時光因而逐漸生變,再度面臨漫長的別離…
Thumbnail
前言: 央行在昨天6/13的理監事會議後,宣佈今天6/14上路第6波選擇性信用管制,主要內容有兩點,第1點是「調升存款準備率1碼(0.25%)」第2點是「調降自然人特定地區第2戶購屋貸款最高成數上限為6成」,所謂的「特定地區」就是直轄市六都與新竹縣市。
Thumbnail
文章將搜尋引擎的運作原理分為三個段落進行介紹,並強調網站結合有效的SEO策略對提升曝光度的重要性。