C语言加载摩斯码数组后结构体morse字段异常为空求助
问题原因分析
核心问题是内存被提前释放:
在while循环中,你为morse分配内存后,将指针赋值给tabMorse[index].morse,紧接着就调用了free(morse)。这会导致结构体里的morse指针变成野指针——它指向的内存已经被操作系统回收,后续访问这块内存属于未定义行为,所以第二次遍历打印时会显示为空(或随机乱码)。
第一次printf能正常显示是巧合:此时morse指向的内存还没被系统重新分配,数据暂时留存,但内存已经不属于你的程序,本质是违规操作。
另外还有两个次要问题:
- 未给
morse字符串添加终止符'\0':C语言字符串必须以'\0'结尾,你只拷贝了.和-,没有添加终止符,printf打印时可能读到乱码。 getline返回值判断优先级错误:read = getline(...) != -1的写法会让read被赋值为布尔值(0或1),而非实际读取的字节数,应该调整括号优先级。
修正后的代码
t_morse *loadTab() { t_morse *tabMorse = malloc(LETTER_NUMBER * sizeof(t_morse)); if (tabMorse == NULL) { printf("Erreur d'allocation mémoire\n"); exit(1); } ssize_t read; size_t len = 0; char index = 0, k = 0, j; char *line = NULL; FILE *f = fopen("morse.txt", "r"); if (f == NULL) { printf("Impossible d'ouvrir morse.txt\n"); free(tabMorse); exit(0); } // 修正getline返回值的判断优先级 while ((read = getline(&line, &len, f)) != -1 && line != NULL) { char *morse = malloc(6 * sizeof(char)); // 5个字符+1个终止符 if (morse == NULL) { printf("Erreur d'allocation mémoire\n"); free(tabMorse); free(line); fclose(f); exit(1); } // 直接使用getline返回的line,无需额外分配stringfinal k = 0; for (j = 0; j < strlen(line); j++) { if (line[j] == '-' || line[j] == '.') { morse[k++] = line[j]; } } morse[k] = '\0'; // 添加字符串终止符 tabMorse[index].morse = morse; tabMorse[index].lettre = index + 48; printf("lettre : %c, morse : %s\n", tabMorse[index].lettre, tabMorse[index].morse); index++; // 移除free(morse),结构体需要保留该内存指针 free(line); // 释放getline分配的内存 line = NULL; } fclose(f); for (index = 0; index < LETTER_NUMBER; index++) { printf("toto %c : %s\n", tabMorse[index].lettre, tabMorse[index].morse); } return tabMorse; }
关键修正点
- 移除
free(morse):结构体的morse指针需要持有分配的内存,直到后续不再使用时统一释放(比如主函数用完数组后,循环free每个tabMorse[i].morse,再freetabMorse)。 - 添加
morse[k] = '\0':确保摩斯码字符串是合法的C字符串。 - 修正
getline的返回值判断逻辑,避免优先级错误。 - 移除不必要的
stringfinal内存分配,直接使用getline返回的line。 - 新增malloc失败的检查,避免空指针访问。
内容的提问来源于stack exchange,提问作者patacoing
相关产品推荐
相关产品推荐

