天天看點

Segmentation Fault

Segmentation fault in Linux

段錯誤應該就是通路了不可通路的記憶體,這個記憶體要麼是不存在的,要麼是受系統保護的。

  • SIGSEGV是在通路記憶體時發生的錯誤,它屬于記憶體管理的範疇
  • SIGSEGV是一個使用者态的概念,是作業系統在使用者态程式錯誤通路記憶體時所做出的處理
  • 當使用者态程式通路(通路表示讀、寫或執行)不允許通路的記憶體時,産生SIGSEGV
  • 當使用者态程式以錯誤的方式通路允許通路的記憶體時,産生SIGSEGV

    使用者态程式位址空間,特指程式可以通路的位址空間範圍。如果廣義的說,一個程序的位址空間應該包括核心空間部分,隻是它不能通路而已。

SIGSEGV産生的可能情況

SIGSEGV在很多時候是由于指針越界引起的,但并不是所有的指針越界都會引發SIGSEGV。一個越界的指針,如果不引用它,是不會引起SIGSEGV的。而即使引用了一個越界的指針,也不一定引起SIGSEGV。

錯誤的通路類型引起

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


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

    return 0;
}
           

通路了不屬于程序位址空間的記憶體

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


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

    return 0;
}
           
#include <stdio.h>
#include <stdlib.h>


int main()
{
    int  i = 0; 
    scanf ("%d", i);  /* should be used &i */ 
    printf ("%d\n", i);

    return 0;
}
           

通路了不存在的記憶體

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


int main()
{
    int *p = NULL;
    *p = 1;

    return 0;
}
           

記憶體越界,數組越界,變量類型不一緻等

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


int main()
{
    char test[1]; 
    printf("%c", test[10]); 

    return 0;
}
           

試圖把一個整數按照字元串的方式輸出

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


int main()
{
    int b = 10; 
    printf("%s\n", b);

    return 0;
}
           

棧溢出了,有時SIGSEGV,有時卻啥都沒發生