c - fclose() 导致崩溃
c - fclose() causes a crash
我在这段代码中遇到问题,它成功执行直到到达 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 */
解法:
如果知道整数的number
,就可以立即分配正确数量的内存。为此,我推荐 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 并非所有库实现都支持。
我在这段代码中遇到问题,它成功执行直到到达 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 */
解法:
如果知道整数的number
,就可以立即分配正确数量的内存。为此,我推荐 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 并非所有库实现都支持。