c - fclose() 导致崩溃

标签 c fclose

我在这段代码中遇到问题,它成功执行直到到达 fclose(fp) 语句,它崩溃了。

void read_file(const char *filename) {
    FILE *fp;
    int num, i=0;

    fp = fopen("numbers.txt","r");

    if (fp == NULL) {
        printf("Couldn't open numbers.txt for reading.\n");
        exit(0);
    }

    int *random = malloc(sizeof(int));
    if (random == NULL) {
        printf("Error allocating memory!\n");
        return;
    }
    while (fscanf(fp, "%d", &num) > 0) {
        random[i] = num;
        i++;
    }
    printf("\nTEST Before close");

    fclose(fp);

    printf("\nTEST After fclose");
}

语句 TEST Before close 打印成功,然后控制台停止打印,所以 TEST After fclose 不打印,光标开始闪烁!

有什么帮助吗? 提前致谢。

最佳答案

问题是

 int *random = malloc(sizeof(int));

只分配ONE 个整数。

如果您的文件中有多个整数,您的while 将递增i 索引,并且您会将您的变量写入无效位置,从而导致内存损坏。这可能会触发段错误,但也可能随时导致奇怪的行为,就像您的情况一样。

   random[i] = num;  /* oops !!! if i>0 memory corruption */ 

解决方案:

如果您知道整数的数量,您可以立即分配正确数量的内存。我推荐 calloc() 为此目的,因为它用于数组分配,并将分配的内存初始化为 0:

int *random = calloc(number, sizeof(int));  

如果您不知道数字,您可以使用 realloc() 逐渐扩展数组的大小。 :

int number = 100;  /* arbitrary initial size*/ 
int *random = malloc(number*sizeof(int));  
...
while (fscanf(fp, "%d", &num) > 0) {
    if (i==number-1) {
        number  += 100;  /* consider allocating 100 more items */
        random = realloc (random, number*sizeof(int)); 
        if (random==NULL) {
            printf("Not enough momory for reading all the numbers.\n");
            exit(1);
         }
    }
    random[i] = num;
    i++;
}

最后一种方法是根据文件大小推断最大整数数:

fseek (fp, 0, SEEK_END);  // go to the end 
long size=ftell (fp);     // get the length of file
fseek (fp, 0, SEEK_SET);  // go to start
long number = size/2 + 1;  // each number is at least 1 digit folowed by a space, except the las one
if (n > INT_MAX) {
     printf("File too big !\n");
     exit(1);
}
int *random = calloc((size_t)number, sizeof(int));  
...

这当然是实用的,但不幸的是,并非所有库实现都支持 SEEK_END。

关于c - fclose() 导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28755359/

相关文章:

c - 带直流电机/编码器的 PID 反馈和位置 Controller

c - 我在哪里可以学习串行/终端接口(interface)编程?

c - 处理文本文件二

c++ - C++ 或 VC++.net 中的套接字编程

c - 二维数组的动态分配

php - 翻译代码 : C Socket to PHP Socket

c - 如何检测 FILE 对象是否已关闭?

检查 fclose() 是否失败并返回特定错误

c - fclose 不可能的正确错误处理(根据联机帮助页)?

c - fclose(stdout) 在使用 freopen 时即使在 NULL 检查后也会导致崩溃