仅当我在调试模式下运行程序时,程序才会收到SIGSEGV分段故障信号

问题描述

我有一个非常简单的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功能仅打印出卡值,西服和位置:

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

现在,当我正常运行主模块时,一切都按预期和预期运行(两张卡都打印有我为其分配的数据,并且该过程以退出代码0结尾),但是当我在调试模式下运行它时,我得到了SIGSEGV我声明carta2并通过调用malloc对其进行初始化时(分段错误)信号。

我知道分段错误意味着进程正在尝试访问不属于它的某个内存地址,但是我什么时候在这里这样做呢?为什么只在调试模式下运行该程序?

如果有帮助,我将CLion ide与CMake结合使用。

解决方法

此内存分配

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

是错误的。你需要写

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

那是您需要为结构类型的对象而不是结构类型的指针分配内存。

或者你可以写

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

其他问题在这里:

  1. 请勿在C中强制转换malloc,这会隐藏严重警告,sizeof运算符的参数似乎无效
Carta carta = (Carta) malloc(sizeof(Carta));

必须更改为:

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

或者您可以使用这种互锁技术,即使用指针本身,该指针将接收要用作sizeof的参数的动态内存

Carta carta = malloc(sizeof(*carta));
  1. 使用NULL(大写)代替null(小写)
    [注意:仅报告首次出现错误,也许还有其他地方]
carta->next = null;
carta->previous = null;

应更改为:

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

为什么只有在调试模式下运行程序才会出现这种情况?

因为未定义的行为可能出于某种原因而有所不同。而且您确实具有不确定的行为。

我什么时候[访问不属于我的记忆]?

Carta的定义如下...

#define Carta struct cartaStruct*

...,例如...

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

...不正确。您正在分配足够的空间来存储struct cartaStruct *类型的对象(一个指针),而您需要的空间要足够大,可以容纳struct cartaStruct类型的结构。此后,当您尝试通过指针carta访问分配的内存时,就会超出分配空间的范围。

您可以这样解决它:

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

,但是这里通常的建议是使用接收指针的变量来确定所需的大小,如下所示:

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

这将为您提供足够的空间容纳carta所指向的任何类型的对象,即使您以后进行更改。


请注意,使用宏作为类型名称的简写是非常不寻常的。使用C的内置机制指定类型别名typedef会更好,更安全:

typedef struct cartaStruct *Carta;