簡體   English   中英

僅當我在調試模式下運行程序時,程序才會收到 SIGSEGV(分段錯誤)信號

[英]Program receives SIGSEGV(Segmentation fault) signal only when I run it in debug mode

我有這個非常簡單的 c 程序:

#define Carta struct cartaStruct*

int main(){
    Carta carta = (Carta) malloc(sizeof(Carta));
    carta->seme[0] = '\0';
    carta->valore = 3;
    carta->posizione = -1;
    carta->next = null;
    carta->previous = null;

    printCard(carta);

    Carta carta2 = (Carta) malloc(sizeof(Carta));
    carta2->seme[0] = '\0';
    carta2->valore = 2;
    carta2->posizione = -1;
    carta2->next = null;
    carta2->previous = null;

    printCard(carta2);
}

其中cartaStruct是表示紙牌的結構:

struct cartaStruct {
    int valore; //card value
    char seme[20]; //card suit
    int posizione; //card position in a line of cards
    struct cartaStruct *next;
    struct cartaStruct *previous;
};

printCard function 只是打印出牌面值、花色和 position:

void printCard(Carta carta) {
    if (carta != null) {
        printf("\nseme: %s", carta->seme);
        printf("\nvalore: %i", carta->valore);
        printf("\nposizione: %i", carta->posizione);
        printf("\n");
    } else {
        printf("La carta è vuota");
    }
}

現在,當我正常運行 main 時,一切都按預期和預期工作(兩張卡都打印了我分配給它們的數據,並且進程以退出代碼 0 結束),但是當我在調試模式下運行它時,我得到一個 SIGSEGV(分段錯誤) 當我聲明carta2並通過調用malloc對其進行初始化時發出信號。

我知道分段錯誤意味着該進程正在嘗試訪問一些不屬於它的 memory 地址,但是我什么時候在這里這樣做呢? 為什么它只在我以調試模式運行程序時發生?

如果有幫助,我正在使用 CLion ide 和 CMake。

本memory配置

Carta carta = (Carta) malloc(sizeof(Carta));

是錯的。 你需要寫

Carta carta = (Carta) malloc(sizeof(`struct cartaStruct`));

那就是你需要為結構類型的 object 分配 memory 而不是結構類型的指針。

或者你可以寫

Carta carta = (Carta) malloc(sizeof( *carta ));

其他問題在這里:

  1. 不要在 C 中投射malloc ,它隱藏了一個嚴重的警告, sizeof運算符的參數似乎無效
Carta carta = (Carta) malloc(sizeof(Carta));

必須改為:

Carta carta = malloc(sizeof(struct cartaStruct));

或者您可以使用指針本身的這種聯鎖技術,它將接收動態 memory 用作sizeof的參數

Carta carta = malloc(sizeof(*carta));
  1. 使用NULL (大寫)代替null (小寫)
    [注:僅報告第一次出現的錯誤,可能還有其他地方也有]
 carta->next = null; carta->previous = null;

應改為:

carta->next = NULL;
carta->previous = NULL;

為什么它只在我以調試模式運行程序時發生?

因為未定義的行為或多或少會出於任何原因以不同的方式表現出來。 而且您確實有未定義的行為。

我什么時候[訪問不屬於我的 memory] 在這里?

Carta的定義是這樣的……

#define Carta struct cartaStruct*

...,分配,例如...

    Carta carta = (Carta) malloc(sizeof(Carta));

……不正確。 您分配的空間足以存儲struct cartaStruct *類型的 object - 一個指針 - 而您需要的是足夠大的空間來容納struct cartaStruct類型的結構。 此后,當您嘗試通過指針carta訪問分配的 memory 時,您超出了分配空間的界限。

你可以像這樣修復它:

    Carta carta = malloc(sizeof(struct cartaStruct));

,但這里通常的建議是使用接收指針的變量來確定所需的大小,如下所示:

    Carta carta = malloc(sizeof(*carta));

這將為您提供足夠的空間來容納carta指向的任何類型的 object,即使您稍后更改。


作為旁注,使用宏作為類型名稱的簡寫是非常不尋常的。 使用 C 的內置機制來指定類型別名typedef會更好、更安全:

typedef struct cartaStruct *Carta;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM