2D动态数组重新分配

时间:2010-02-06 13:26:45

标签: c programming-languages

我有这个程序的问题。我们的想法是从文本文件中读取字符串,并将它们包含在具有恒定列数和不同行数的2D动态数组中。如果初始行数不足以包含所有字符串,则必须重新分配阵列的内存块。代码正在编译好,但执行是不可能的。

#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define SIZE 80
#define DELTA 5

char** include(char b[SIZE],char** p,int n,int k,int flag);
void output(char **p,int k);

int main(void)
{
char **ptr;  
FILE *fp;    
int i=0,koef=1;
char buffer[SIZE];

 if((ptr=(char **)malloc(DELTA*sizeof(char *)))==NULL){  
  printf("Error!Memory not allocated!\n");
  exit(1);
 }
 if((fp=fopen("test.txt", "r")) == NULL) {  
            printf("Cannot open file.\n");
            exit(1);
 }
 do{    
  if(fgets(buffer,sizeof(buffer),fp)==NULL){  
         printf("Error while reding file!\n");
  exit(1);
  }  
  if(i<(DELTA*koef))  
  ptr=include(buffer,ptr,i,koef,1);                                                                                  
 else {
         koef++; 
         ptr=include(buffer,ptr,i,koef,2);
 } 
  i++;    
  }while(!feof(fp));  

 free(ptr);        

 return 0;
}

char** include(char b[SIZE],char** p,int n,int k,int flag)
{
  switch(flag){
      case 1: *(p+n)=(char *)malloc(sizeof(b));
              strcpy( *(p+n),b);
       break;
      case 2: if((p=(char **)realloc(p,k*DELTA*sizeof(char *)))==NULL){ 
                  printf("Error!Memory not allocated!\n");
                  exit(1);
       }
      *(p+n)=(char *)malloc(sizeof(b));
      strcpy(*(p+n),b);     
      break;
}
  return p;
 }

void output(char **p,int k)
{
  int j;
  for(j=0;j<k;j++)
  printf("%s\n",*(p+j));
}

2 个答案:

答案 0 :(得分:2)

指定数组参数的大小无效。

void func(char b[SIZE]);

相当于

void func(char *b);

因此,当你说

case 1: *(p+n)=(char *)malloc(sizeof(b));

sizeof将计算为指向char的指针的大小。尝试使用

case 1: *(p+n)=(char *)malloc(SIZE * sizeof(b));

如果您说

,则会发生同样的错误
*(p+n)=(char *)malloc(sizeof(b));

您可以将其更改为

*(p+n)=(char *)malloc(SIZE * sizeof(b));

您应该设置大小,以便缓冲区有整个行的空间,包括换行符和终止\ 0。否则,strcpy将无法正常工作。无论如何你应该使用strncopy。完成这些更改后,一旦达到文件末尾,fgets将返回0,并且程序将报告“reding file!”时出错。您应该相应地更改读取循环的终止。

此外,您实际上并未使用多维数组。您正在使用指向字符数组的指针数组。在C中,二维数组将被分配在连续的存储器块中并以行主要顺序访问。这样就可以了,因为所有行都应该具有相同的长度。然而,您正在尝试维护一个指针数组,这些指针又指向行。这也有效,但在技术上我们称之为C中的多维数组。它称为Iliffe vector或简称​​数组

总而言之,您的代码相互交织,难以理解。您应该尝试简化您的程序,这将使您在将来更容易发现错误。

答案 1 :(得分:0)

fgets()在到达文件末尾或出现错误时返回NULL。在你的情况下, 因为您正在检查do-while循环,所以当您在检查fgets()的返回值时退出时,永远不会达到条件feof(fp)
你应该这样做:


while(fgets(buffer,sizeof(buffer),fp)!=NULL)
{
  if(ferror(fp))
  {
    printf("Error Reading file\n");
    exit(1);
  }
  if(i <(DELTA*koef))
  ptr=include(buffer,ptr,i,koef,1);
  else {
         koef++;
         ptr=include(buffer,ptr,i,koef,2);
  }
  i++;
}