我有一个动态读取文件到2D数组的问题。我已经阅读了很长时间但我仍然不知道如何强制我的代码工作。
我的代码:http://codepaste.net/3hcbtn
#include <stdio.h>
#include <stdlib.h>
int main(){
//This program reads a file consisting of 5 columns of numbers.
//We assume that we don't know the number of rows of that file.
double **x,**t;
int i,j,COL=5;
x=malloc(COL*sizeof(double*));
for(i=0;i!=COL;i++){x[i]=calloc(1,sizeof(double));}
t=malloc(COL*sizeof(double*));
FILE *f;
f=fopen("realloc2.dat","r");
j=0;
for(;;){
for(i=0;i!=COL-1;i++){
fscanf(f,"%lf, ",&x[i][j]);
t[i]=realloc(x[i],sizeof(x[i]+1));
x[i]=t[i];
}
fscanf(f,"%lf\n",&x[COL-1][j]);
if(feof(f)!=0){break;}
t[COL-1]=realloc(x[COL-1],sizeof(x[COL-1]+1));
x[COL-1]=t[COL-1];
j++;
}
for(i=0;i!=COL;i++){
free(x[i]);
}
free(x);
free(t);
fclose(f);
return 0;
}
输出:
*** Error in `./realloc2_2': realloc(): invalid next size: 0x0000000001d9d040 ***
[...]
Segmentation fault
我有一个包含COL列的文件,但我们不知道它有多少行,这就是我尝试使用realloc()的原因。我花了很多时间来修理它......你能帮助我吗?
谢谢。
答案 0 :(得分:0)
这个想法并不错,但你有点不对劲:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define REALLOC_GROW 10
// ALL CHECKS OMMITTED!
int main()
{
//This program reads a file consisting of 5 columns of numbers.
//We assume that we don't know the number of rows of that file.
int i, COL = 5;
double *row, **table, **cp;
int allocated = 0, needed = 0;
// one row, just as the name suggests
// I would have choosen a simple array on the stack
// e.g.: double row[5] = {0.0};
// but it is your choice.
row = malloc(COL * sizeof(double));
// set pointer to NULL to avoid initial malloc
table = NULL;
FILE *f;
f = fopen("realloc2.dat", "r");
for (;;) {
// check if we have enough rows preallocated
// this is also the case in the very beginning
if (needed >= allocated) {
// reserve memory for ten (more) pointers
cp = realloc(table, (needed + REALLOC_GROW) * sizeof(double *));
table = cp;
// allocate memory for the ten rows
for (i = 0; i < REALLOC_GROW; i++) {
table[needed + i] = malloc(COL * sizeof(double));
}
// keep the amount of rows pre-allocated
allocated += REALLOC_GROW;
}
// read one row (assuming one row is on one line ending with '\n')
fscanf(f, "%lf, %lf, %lf, %lf, %lf\n", &row[0], &row[1], &row[2], &row[3],
&row[4]);
// copy result into table
memcpy(table[needed], row, COL * sizeof(double));
// prepare for next row;
needed++;
// check if we are done
// could (and should!) have been tested already with fscanf
// but I ommitted all tests including the tests of the
// return of fscanf
if (feof(f)) {
break;
}
}
// print it to check it
for (i = 0; i < needed; i++) {
printf("%f, %f, %f, %f, %f\n", table[i][0], table[i][1], table[i][2],
table[i][3], table[i][4]);
}
// clean up
free(row);
for (i = 0; i < allocated; i++) {
free(table[i]);
}
free(table);
fclose(f);
exit(EXIT_SUCCESS);
}
使用shell one-liner的可憎创建的输入文件:
for i in `seq 1 1 33`;do c1=$(shuf -i 10-99 -n 1);c2=$(shuf -i 10-99 -n 1);c3=$(shuf -i 10-99 -n 1);c4=$(shuf -i 10-99 -n 1);c5=$(shuf -i 10-99 -n 1); echo "$c1.32, $c2.32, $c3.32, $c4.23, $c5.23" >> realloc2.dat;done
答案 1 :(得分:0)
像这样解决:
#include <stdio.h>
#include <stdlib.h>
int main(void){
double **x;
int ROW = 5;//Provisional value
int COL = 5;
int c, r = 0, rows;
FILE *fp = fopen("realloc2.dat","r");
if(fp == NULL){
perror("file can't open");
exit(EXIT_FAILURE);
}
x = malloc(ROW * sizeof(double*));//malloc(ROW * sizeof(*x));
for(;;++r){
if(r == ROW){
ROW += 5;//fitly size expansion. e.g ROW *= 2
if((x = realloc(x, ROW * sizeof(*x))) == NULL){
perror("failed realloc");
exit(EXIT_FAILURE);
}
}
if((x[r] = malloc(COL * sizeof(double))) == NULL){
perror("failed malloc");
exit(EXIT_FAILURE);
}
for(c = 0; c < COL; ++c){
if(1 != fscanf(fp, "%lf", &x[r][c]))
goto readend;
}
}
readend:
rows = r;
if(c != 0){
puts("data are insufficient.");
} else {
//test print
for(r = 0; r < rows; ++r){
for(c = 0; c < COL; ++c){
if(c)
putchar(' ');
printf("%5.2f", x[r][c]);
}
puts("");
}
}
fclose(fp);
//deallocate
for(r = 0; r <= rows; ++r){
free(x[r]);
}
free(x);
return 0;
}