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

使用realloc后所有数组索引指向同一数据的技术问题排查

C语言动态字符数组异常:所有元素显示同一内容的问题排查与解决

问题根源

兄弟,这个问题我太熟了!你代码里的lines[counter] = nextline;这行就是核心bug!

nextline是一个栈上的局部字符数组(char nextline[1024];),每次循环执行fgets时,都会把读取到的玩家数据覆盖到这块固定的栈内存里。而你只是把nextline的内存地址赋值给lines数组的每个元素——这意味着lines里的300个指针,全指向了同一块内存区域!

当循环结束后,nextline里存的是最后一次读取的玩家数据,所以你后续访问所有lines元素时,看到的自然都是这最后一份内容。更糟的是,nextline是栈变量,函数执行完毕后这块内存会被系统回收,后续访问还可能触发崩溃或读取垃圾值的未定义行为。

解决方案

要解决这个问题,你需要为每个读取到的字符串分配独立的堆内存,并把内容复制进去,而不是直接复用栈内存的地址。这里有两种常用方法:

方法1:用strdup快速复制字符串(简便但依赖POSIX标准)

strdup会自动完成内存分配和字符串复制,直接替换赋值那一行即可:

lines[counter] = strdup(nextline);

注意:strdup不是C语言标准库函数,但绝大多数主流编译器(GCC、Clang、MSVC等)都支持它。

方法2:手动malloc+strcpy(标准C兼容,更稳妥)

如果需要严格遵循C标准,或者要处理内存分配失败的情况,推荐用这种方式:

// 为当前字符串分配内存:长度+1(用于存储字符串终止符'\0')
lines[counter] = malloc(strlen(nextline) + 1);
// 一定要检查内存分配是否成功,避免空指针访问
if (lines[counter] == NULL) {
    // 分配失败时,要先释放已分配的内存,避免泄漏
    for (int i = 0; i < counter; i++) {
        free(lines[i]);
    }
    free(lines);
    fclose(fd);
    printf("内存分配失败!\n");
    return;
}
// 把nextline的内容复制到新分配的内存里
strcpy(lines[counter], nextline);

额外注意事项

使用完lines数组后,别忘了释放内存避免泄漏:

// 先逐个释放每个字符串的内存
for (int i = 0; i < *numElements; i++) {
    free(lines[i]);
}
// 最后释放lines数组本身
free(lines);

内容的提问来源于stack exchange,提问作者Rafael Botas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:24:16