C 只有在调试模式下运行时,程序才会接收SIGSEGV(分段故障)信号
我有一个非常简单的c程序:C 只有在调试模式下运行时,程序才会接收SIGSEGV(分段故障)信号,c,segmentation-fault,dynamic-memory-allocation,clion,C,Segmentation Fault,Dynamic Memory Allocation,Clion,我有一个非常简单的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 = nu
#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");
}
}
现在,当我正常运行main时(两张卡都打印了我分配给它们的数据,进程以退出代码0结束),一切都按照预期工作,但当我在调试模式下运行它时,当我声明carta2
并通过调用malloc
对其进行初始化时,我会得到一个SIGSEGV(分段故障)信号
我知道分段错误意味着进程试图访问一些不属于它的内存地址,但我在这里什么时候这样做?为什么只有在调试模式下运行程序时才会发生这种情况
如果有帮助的话,我正在将CLion ide与CMake一起使用。此内存分配
Carta carta = (Carta) malloc(sizeof(Carta));
这是错误的。你需要写作
Carta carta = (Carta) malloc(sizeof(`struct cartaStruct`));
也就是说,您需要为结构类型的对象而不是结构类型的指针分配内存
或者你可以写
Carta carta = (Carta) malloc(sizeof( *carta ));
其他问题如下:
malloc
,它隐藏了一个严重的警告,sizeof
运算符的参数似乎无效Carta Carta=(Carta)malloc(sizeof(Carta));
必须更改为:
Carta-Carta=malloc(sizeof(struct-cartaStruct));
或者,您可以使用这种互锁技术,即使用指针本身来接收动态内存,以用作sizeof
Carta Carta=malloc(sizeof(*Carta));
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;
Carta Carta=(Carta)malloc(sizeof(Carta))
这不应该是Carta Carta=(Carta)malloc(sizeof(Carta))
sizeof(carta)
而不是sizeof(carta)
No,@sourabhchour。那里的分配规模存在问题,但您建议的特定更改根本没有任何区别。