C语言结构体数组中file_name成员值始终相同的问题排查
问题原因及解决办法
问题原因
你的代码中所有结构体的file_name都显示最后一行的tileX,核心问题是结构体里的file_name是一个指针,没有独立的内存空间:
- 循环中每次调用
fgets,都会把读取的内容写入同一个str数组,覆盖之前的数据 strtok返回的指针指向的是str数组内部的位置,你直接把这个指针赋值给tileData[i].file_name,导致所有结构体的file_name都指向了同一个str数组- 当循环执行到最后一行时,
str数组里存储的是最后一行的内容,所以所有结构体的file_name指针都会指向这个最终内容,打印出来自然全是tileX
解决办法
方法一:为每个file_name分配独立内存(推荐)
通过复制字符串的方式,给每个结构体的file_name分配专属内存,避免被后续循环覆盖:
修改switch中case 0的代码:
case 0: // 使用strdup复制字符串,自动分配内存 tileData[i].file_name = strdup(item); break;
如果你的编译环境不支持strdup,可以手动用malloc+strcpy实现:
case 0: // 计算字符串长度,分配足够内存(+1是为了存储字符串结束符'\0') tileData[i].file_name = (char*)malloc(strlen(item) + 1); if (tileData[i].file_name != NULL) { strcpy(tileData[i].file_name, item); } break;
⚠️ 注意:使用动态分配内存后,程序结束前需要释放这些内存,避免内存泄漏,在打印循环结束后添加:
for (int k = 0; k < 10; k++) { free(tileData[k].file_name); }
方法二:在结构体中使用固定大小字符数组
直接修改结构体定义,把char* file_name换成固定长度的字符数组,让每个结构体自带存储文件名的空间:
struct tile { char file_name[20]; // 根据实际文件名长度调整大小,确保足够存储 int l,u,r,d; }; typedef struct tile tile_t;
然后在switch的case 0中用strcpy复制内容:
case 0: strcpy(tileData[i].file_name, item); break;
这种方法无需手动管理内存,适合文件名长度可控的场景,不会出现内存泄漏问题。
内容的提问来源于stack exchange,提问作者SirMino
相关产品推荐
相关产品推荐

