проблемы malloc вызывают ошибку сегментации - PullRequest
0 голосов
/ 15 декабря 2011

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct paragraph{
   char **words;
}paragraph;

typedef struct text{
   char name[100];
   paragraph  *list;
}text;

void readFileContent(FILE *file, paragraph *pa, int size){

   char localString[100];

   pa->words = (char **)malloc(size * sizeof(char *));
   int i = 0, z;

   while(fscanf(file, "%s", localString) == 1 && i < size){
      z = strlen(localString);
      pa->words[i] = (char *)malloc(z + 1);

      strcpy(pa->words[i], localString);
      i++;
   }

}

void main(){
      int i = 0, n, z;
   FILE *file;
   text *localText;
   localText = (text *)malloc(sizeof(text));

   openFile(&file, "test.txt");
   i = countWords(file);

   i = i / 50 + 1; // calculate the number of section need for the text

   localText->list = calloc(sizeof(paragraph *), i);

   for(n = 0; n < i ; n++){
      printf("Paragraph - %d\n", n);
      readFileContent(file, &localText->list[i], 50);

   }

   for(n = 0; n < i ; n++){
      printf("Paragraph - %d", n);
      for(z = 0; z < 50; z++){
      printf("no. %d\n", z);
      printf("%s\n", localText->list[n].words[z]);
      }
   }

}

Когда я пытаюсь запустить программу, я получаю ошибку сегментации в контуре печати внизу. Я думаю, что это вызвано некоторой проблемой с выделением памяти, но я не могу понять, почему.

Обновление 1 Я изменил код, чтобы использовать трехмерный массив для хранения текстовых сегментов, но я все еще получаю ошибку сегментации, когда пытаюсь выделить память с помощью malloc.

localText->list[i][n] = malloc(100 * sizeof(char));

это измененный код.

typedef struct {
   char name[100];
   char  ***list;
}text;

int main(){
   int i = 0, n, z,wordCount, sections;
   FILE *file;
   text *localText;

   openFile(&file, "test.txt");
   wordCount = countWords(file);


   sections = (wordCount / 50) + 1;

   localText = malloc(sizeof(text));
   localText->list = malloc(sections * sizeof(char **));

   for(i = 0; i < sections; i++)
      localText->list[i] = malloc(50 * sizeof(char *));
      for(n = 0; n < 50; n++)
         localText->list[i][n] = malloc(100 * sizeof(char));

   readFileContent(file, localText->list, 50);

   freeText(localText);

   return 1;

}

Ответы [ 3 ]

7 голосов
/ 15 декабря 2011

В вашем коде много ошибок. Вот самые серьезные из них:

1) Указатель-указатель не является многомерным массивом . Если вы используете указатель к указателю для доступа к многомерному динамически размещаемому массиву, то этот массив должен быть размещен таким образом, который имеет смысл для указателя на указатель.

Похоже, что вы пытаетесь динамически выделить массив указателей, а затем для каждого указателя в этом массиве выделить массив данных. Однако ваш код этого не делает, у вас слишком много уровней косвенности для вашего кода, чтобы иметь какой-либо смысл. Например, paragraph *list;, зачем вам указатель на структуру, содержащую указатель на указатель?

Вам нужно упростить ваши структуры данных. Вместо этого я предлагаю сделать следующее:

typedef struct {
   char   name[100];
   char** list;
} text;

2) Не называйте typedef так же, как тег struct, это рано или поздно приведет к конфликту пространства имен. Вам даже не нужен тег struct, когда typedef: используется структура, вместо этого делайте, как в моем примере выше.

3) Никогда не печатайте результат malloc / calloc на языке Си. Это скрывает предупреждения компилятора и ошибки. Бесчисленное множество подробных сообщений о причинах, по которым можно найти здесь, на SO .

4) Поскольку это размещенная программа, работающая в операционной системе (я могу сказать, используя обработку файлов), main не может вернуть ничего, кроме int. Измените ваше определение main на int main() или , оно не будет компилироваться на стандартном компиляторе C .

5) for(n = 0; n < i ; n++) ... list[i]. Как вы можете определить по собственному коду, не стоит использовать имя переменной i для чего-либо, кроме итератора цикла. (i фактически означает итератор). Вот почему у вас есть ошибка.

6) Вы должны закрыть открытый файл, когда закончите с ним, через fclose().

7) Вы должны освободить динамически выделенную память, когда закончите с ней, через free().

5 голосов
/ 15 декабря 2011
 readFileContent(file, &localText->list[i], 50);

Вы инициализируете элемент one-past-the-last-th здесь, но не инициализируете все остальные элементы списка.Попробуйте list[n] вместо.

0 голосов
/ 15 декабря 2011

кажется, что вы сделали здесь опечатку

for(n = 0; n < i ; n++){
      printf("Paragraph - %d\n", n);
      readFileContent(file, &localText->list[i], 50);

   }

не должно быть

for(n = 0; n < i ; n++){
      printf("Paragraph - %d\n", n);
      readFileContent(file, &localText->list[n], 50);

   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...