问题描述
#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 ));
,
其他问题在这里:
- 请勿在C中强制转换
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;