2011-12-15 2 views
0

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

#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]); 
     } 
    } 

} 

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

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

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; 

} 
+2

Вы должны запустить свою программу в отладчике. Когда он выйдет из строя, вы сможете проверить значения переменных. –

+2

Впервые я вижу 'for (n = 0; n

+0

@BlagovestBuyukliev: Это, вероятно, корень причина ошибки здесь. Использование 'i' для привязки массива - злая идея. – thiton

ответ

7

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

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

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

Необходимо упростить структуру данных. Я предлагаю сделать так, вместо:

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

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

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

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

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

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

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

+1

Хорошо читаю ваш повтор, получил, чтобы я понял, что я не должен использовать ярлыки при кодировании, так как это явно затрудняет для себя, чтобы я обнаружил ошибку, спасибо за это. На стороне не актуальная проблема. Если у меня есть список, содержащий списки строк, это массив 3d или 2d? –

+0

@ user1018046 Это мудро. Как правило, никогда не пишите строку кода, в которой вы не знаете, почему вы используете определенную практику или метод, в C есть много подводных камней, как есть. Список списков строк действительно представляет собой 3D-массив, если вы его правильно распределите. C довольно сложна, когда речь заходит о массивах с несколькими измерениями, [comp.lang.c.faq] (http://c-faq.com/aryptr/index.html) является _excellent_, одной из лучших публикаций в C. Я настоятельно рекомендую прочитать вопрос 6.16. – Lundin

5
readFileContent(file, &localText->list[i], 50); 

Вы инициализирует один-пришедшего к последним-й элемент здесь, а не инициализирует все остальные элементы списка. Вместо этого попробуйте list[n].

0

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

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); 

    } 
Смежные вопросы