繁体   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