You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:01:18