2011-12-15 20 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]); 
     } 
    } 

} 

私がプログラムを実行しようとすると、下の印刷ループにセグメント違反が発生します。私はそれがメモリを割り当てることにいくつかの問題が原因だと思うが、私は理由を理解することはできません。

アップデート1 私は、テキストセグメントを格納するための3次元配列を使用するコードを変更しましたが、私は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; 

} 
+2

デバッガでプログラムを実行する必要があります。クラッシュすると、変数の値を調べることができます。 –

+2

for(i = 0; i

+0

@BlagovestBuyukliev:おそらく根ですここのエラーの原因。配列の束縛に 'i'を使うのは悪い考えです。 – thiton

答えて

7

すべきではない、ここで

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

    } 

をタイプミスを行っているようです。ここで最も深刻なものは、次のとおり

1)ポインタへのポインタは、多次元配列ありません。ポインターツーポインターを使用して多次元で動的に割り当てられた配列にアクセスする場合、その配列はポインタへのポインタに意味をなされる方法で割り当てられる必要があります。

ポインタの配列を動的に割り当てようとしているように見えますが、その配列の各ポインタに対して、データの配列を割り当てます。しかし、あなたのコードはこれをしません、あなたのコードが意味をなさないように間接レベルが多すぎます。たとえばparagraph *list;のように、ポインタへのポインタを含む構造体へのポインタが必要なのはなぜですか?

データ構造を簡素化する必要があります。私は、この代わりのように行うことを提案する:

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

2)構造体タグと同じものが、これは遅かれ早かれ名前空間の競合のトラブルにあなたを取得するのtypedefに名前を付けないでください。 typedefのときに構造体タグを必要とせず、上記の例のように構造体を作成する必要はありません。

3)malloc/callocの結果をC言語でtypecastしないでください。これにより、コンパイラの警告やバグが隠されます。 SOに理由が見つからない理由に関する詳細な記事は数え切れないほどあります。

4)これはOS上で実行されているホストされたプログラムです(ファイル処理を使用するとわかります)ので、mainはint以外のものを返すことはできません。メインの定義を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); 

他のすべてのリスト要素を初期化していない間は、ここ1 - 過去 - 最後の番目の要素を初期化しています。代わりにlist[n]を試してください。

0

は、あなたがそれはあなたのコードのバグがたくさんある

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

    } 
関連する問題