说我有一个numbers.txt
文件,其中包含未指定大小的双数字。
我需要将这些值动态存储在double *note
指针中以供以后使用。
我尝试了以下代码,但它提供了核心转储:
FILE *ifile = fopen("numbers.txt", "r");
double *note;
int i = 1;
note = (double *) malloc( i * sizeof( double));
fscanf( ifile, "%lf", ¬e[0]);
while ( !feof( ifile)) {
i++;
note = (double *) realloc( note, i * sizeof( double));
fscanf( ifile, "%lf", ¬e[i]);
}
for (n=0; n < i; n++) {
printf( "%lf\n", note[i]);
}
答案 0 :(得分:1)
每次使用note[i]
时,您的代码都会从其边界外访问数组。
在(wrong)while循环中,它总是超过最后一个元素(例如,在第一次迭代i
中变为2,分配了足够的空间用于两个double
s,但是你访问第三个note[2]
。
打印时,您使用n
作为增加循环索引,但始终打印note[i]
而不是note[n]
。
检查所有使用的库函数的返回值也是一种很好的做法,例如open
,new
,realloc
和scanf
。
这些问题的快速解决方法可能是以下代码段。请注意,我使用了与您相同的重新分配策略(每次),但正如@Serge Ballesta指出的那样,这可能效率低下。例如,请看@ Jean-FrançoisFabre的答案。
#include <stdio.h>
#include <stdlib.h>
int main() {
double value,
*note = NULL,
*newptr = NULL;
int i,
size = 0;
char file_name[] = "numbers.txt";
FILE *ifile = fopen(file_name, "r");
if ( !ifile ) {
fprintf(stderr, "Error while opening file %s.\n", file_name);
exit(EXIT_FAILURE);
}
while ( fscanf(ifile, "%lf", &value) == 1 ) {
size++;
newptr = realloc(note, size * sizeof(double));
if ( !newptr ) {
fprintf(stderr, "Error while reallocating memory.\n");
free(note);
exit(EXIT_FAILURE);
}
note = newptr;
note[size - 1] = value;
}
for (i=0; i < size; i++) {
printf( "%lf\n", note[i]);
}
free(note); // <-- don't leak memory!
fclose(ifile);
return EXIT_SUCCESS;
}
答案 1 :(得分:0)
你的i从0传递到2,并且你的索引永久地超出你的界限:你分配2个双打,并写入索引2,这是第三个。 别忘了关闭文件。 并且最终打印使用i应该使用n。混合常用字母(i代表循环索引,n代表极限)并不好,最后每个人都会感到困惑。
最好简化/分解代码,如下所示,以避免错误:
作为奖励,我添加了一种避免每次重新分配的机制,这在性能方面不是很好。
以下代码已经过测试并正常工作
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *ifile = fopen("numbers.txt", "r");
double v,*note=NULL;
int i = 0,n;
int alloc_step = 10;
int note_size = 0;
while ( !feof( ifile)) {
fscanf( ifile, "%lf", &v);
if ((i % alloc_step)==0)
{
note_size += alloc_step;
note = (double *) realloc( note, note_size * sizeof( double));
}
note[i++] = v;
}
for (n=0; n < i; n++) {
printf( "%lf\n", note[n]);
}
fclose(ifile);
}