Перераспределение двумерных динамических массивов - PullRequest
1 голос
/ 06 февраля 2010

У меня проблемы с этой программой. Идея состоит в том, чтобы читать строки из текстового файла и включать их в двухмерный динамический массив с постоянным количеством столбцов и различным количеством строк. Если исходного числа строк недостаточно для включения всех строк, необходимо перераспределить блок памяти для массива. Код компилируется нормально, но выполнение невозможно.

#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 ]

2 голосов
/ 06 февраля 2010

Указание размера аргумента массива не имеет никакого эффекта.

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, когда будет достигнут конец файла, и ваша программа сообщит «Ошибка при чтении файла!». Вы должны соответствующим образом изменить завершение цикла чтения.

Кроме того, вы на самом деле не используете многомерный массив. Вы используете массив указателей на массивы символов. В C 2-мерный массив будет размещен в непрерывном блоке памяти и доступен в основном порядке строк. Это было бы хорошо в вашем случае, потому что все строки должны иметь одинаковую длину. Тем не менее, вы пытаетесь поддерживать массив указателей, которые в свою очередь указывают на строки. Это также работает, но технически это не то, что мы бы назвали многомерным массивом в C. Он называется вектор Iliffe или просто массив .

В целом, ваш код довольно запутан и труден для понимания. Вам следует попытаться упростить вашу программу, которая в будущем значительно облегчит вам поиск ошибок.

0 голосов
/ 06 февраля 2010

fgets () возвращает значение NULL, когда достигнут конец файла или произошла ошибка. В твоем случае, когда вы проверяете цикл do-while, условие feof(fp) никогда не достигается при выходе из проверки возвращаемого значения fgets ().
Вы должны сделать так:


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++;
}


...