我试图简单地将一个从向量中定义为Card的元素赋值给mtr[i][j],这是一个存储在堆中的2d矩阵,但是调试器声称有一个分段错误。
我想我尝试了一切,尝试使用静态矩阵,检查手表是否为NULL,手动分配结构的每个成员。
出于好奇,我试图将矩阵的类型更改为int和char。即便如此,分配(在适当更改赋值之后)仍然无法工作。
int g_rows = 0, g_cols=0;
typedef struct{
char color;
int points;
}Segment;
typedef struct{
Segment h;
Segment v;
}Card;
Card** loadBoard(char* fileName, Card* cards) {
short tileRef; short rot;
short i=0;
FILE* fp = fopen(fileName,"r"); if(fp == NULL) return NULL;
if(fscanf(fp, "%hd %hd\n", &g_rows, &g_cols) == 0) {fclose(fp); return NULL;}
Card **mtr = (Card**)malloc(g_rows * sizeof(**mtr)); if(!mtr){printf("Error on first malloc.\n");}
for(short i = 0; i<g_rows; i++) {
mtr[i] = (Card*)malloc(g_cols * (sizeof (*mtr)) );
if(!mtr[i]) printf("error on 2nd malloc.\n");
}
i=0;
while(!feof(fp)){
for(short j=0;j<g_cols;j++) {
fscanf(fp, "%d/%d\n", &tileRef, &rot);
if (tileRef != -1)
mtr[i][j] = (rot == 0) ? cards[tileRef] : (Card) {.h = cards[tileRef].v, .v = cards[tileRef].h};
else
mtr[i][j] = (Card){{.points=-1,.color='\0'},{.points=-1,.color='\0'}};
}
fscanf(fp,"\b\n"); i++;
}
fclose(fp);
return mtr;
}我试图搜索这样的问题,但我最终研究了2d动态分配的代码示例,这太奇怪了。
也许我错过了一些重要的事情,但我真的不能抓住它。
最终编辑:我发现我正在使用的che编译器(来自MingW的Clang/LLVM)是罪魁祸首。我尝试将设置为CLion中的默认工具链,但没有出现任何问题。
发布于 2020-12-23 04:41:49
问题似乎是malloc调用中微妙的键入。
g_rows * sizeof(Card)分配空间。但是由于地铁被用来存储卡片指针,而不是卡片,所以我们想要g_rows * sizeof(Card*)。g_cols * sizeof(Card*)分配空间。但是,由于每个矩阵行都用于存储卡片,而不是卡片指针,所以我们需要g_cols * sizeof(Card)。此错误尤其严重,因为sizeof(Card*)小于sizeof(Card),因此没有分配足够的内存。从文件中读取数据的while循环下面还有一个潜在的问题。只要文件继续,循环就会迭代,而不检查i变量是否仍在范围内。因此,如果文件的格式不正确,它可能导致这段代码删除矩阵的末尾和段错误。
注释:我强烈建议使用瓦兰或地址消毒剂(ASan)。这些工具自动检查与内存相关的错误,对于调试这些问题是非常宝贵的。
https://stackoverflow.com/questions/65418574
复制相似问题