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

文件读取函数崩溃排查:读取多行至结构体时程序异常

帮你排查程序崩溃的几个关键问题

嘿,我看了你的代码,发现好几个直接导致程序崩溃的核心问题,咱们一个个拆解清楚:

1. 野指针写入触发内存错误

你在loadfromfile里定义了char* string[40];,这是一个指针数组,但每个指针都没有指向有效的可写内存空间。直接用strcpy(string[i], line)往这些未初始化的指针里写数据,相当于往随机的内存地址写入,必然触发程序崩溃。

修复方法:
要么给每个指针分配足够的内存:

char* string[40];
// 在strcpy前先分配内存,+1是给字符串结束符'\0'留位置
string[i] = malloc(strlen(line) + 1); 
if (string[i] == NULL) {
    perror("malloc failed");
    fclose(f);
    return NULL;
}
strcpy(string[i], line);

或者直接用二维数组(更简单,适合固定长度的场景):

char string[40][100]; // 最多存40行,每行100字符

2. 循环中重复的i++导致逻辑混乱+数组越界

看你这两段循环:

for(i = 0; i<SIZE*2; i++){
 strcpy(hashtbl[i].subscript, string[i]);
 i++; // 这里多了一个i++!
}
for(i = 1; i<SIZE*2; i++){
 strcpy(hashtbl[i].value, string[i]);
 i++; // 又多了一个!
}
  • 每次循环i会增加2,导致你跳过了一半的元素,逻辑完全错误;
  • 更严重的是,你的init_hashtbl只分配了SIZE个Hashtbl元素,但循环条件是i<SIZE*2,这会访问超出分配范围的内存,触发数组越界崩溃。

如果你的逻辑是文件里的行成对出现(奇数行是subscript,偶数行是value),正确的循环应该是这样:

for(i = 0; i < SIZE; i++){
    if (string[2*i] != NULL) {
        strcpy(hashtbl[i].subscript, string[2*i]);
    }
    if (string[2*i+1] != NULL) {
        strcpy(hashtbl[i].value, string[2*i+1]);
    }
}

3. 字符串常量不可修改,写入触发权限错误

在init_hashtbl里,你给subscript和value赋值了字符串常量:

hashtbl[i].subscript = "ZERO";
hashtbl[i].value = "ZERO";

字符串常量是存储在只读内存区的,后面用strcpy往里面写数据会触发内存访问权限错误,直接崩溃。

修复方法:初始化时给指针分配可写的内存:

Hashtbl* init_hashtbl(){
 Hashtbl* hashtbl = calloc(SIZE, sizeof(Hashtbl));
 if (hashtbl == NULL) {
     perror("calloc failed");
     return NULL;
 }
 for(int i = 0; i<SIZE; i++){
     // 分配足够的内存(和line的长度匹配,比如100字节)
     hashtbl[i].subscript = malloc(100);
     hashtbl[i].value = malloc(100);
     if (hashtbl[i].subscript == NULL || hashtbl[i].value == NULL) {
         perror("malloc failed");
         // 释放已分配的内存,避免泄漏
         for(int j = 0; j < i; j++){
             free(hashtbl[j].subscript);
             free(hashtbl[j].value);
         }
         free(hashtbl);
         return NULL;
     }
     strcpy(hashtbl[i].subscript, "ZERO");
     strcpy(hashtbl[i].value, "ZERO");
 }
 return hashtbl;
}

4. 文件打开失败后未终止函数,导致空指针操作

当fopen(path, "r")返回NULL时,你只打印了FILE NO FOUND!,但没有终止函数,程序会继续执行后面的while(fgets(...))和fclose(f),这时候f是NULL,调用fclose(NULL)会直接崩溃。

修复方法:在打印错误后立即返回:

if(f == NULL){
 printf("FILE NO FOUND!");
 return NULL; // 或者用exit(1)终止程序
}

额外建议:处理fgets读取的换行符

fgets会把文件中的换行符\n也读进line里,如果不需要的话,可以去掉:

while(fgets(line, sizeof(line), f)!=NULL){
    // 去掉换行符
    line[strcspn(line, "\n")] = '\0';
    // 后续处理...
}

最后,记得在程序结束时释放所有分配的内存,避免内存泄漏哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:36:10