2017-07-30 17 views
-5

このプログラムは、コードの先頭にハードコードされた名前と年齢の配列から名前と年齢の値を含む構造体配列を作成することになっています。 私は、main関数で配列を宣言してから、insert関数内でその配列にメモリを割り当てるよう求められました。プログラムは罰金コンパイルし、私が取得することになってるの出力は次のようになります。C - 出力にヌル値とセグメンテーションフォールトが含まれています

名:サイモン

年齢:22

名前:スージー

年齢:24

名:アルフレッド

年齢:106

名:チップ

年齢:6

などなど

私が手出力は次のようなものですが:

名:サイモン

年齢:22

名:( null)

年齢:33

名前:スージー

年齢:24

名:(ヌル)

年齢:33

名前:スージー

年齢:24

... .. セグメンテーションフォールトが発生しました。

名前の一部が2回表示され、名前の一部がヌルであり、出力の最後にセグメンテーション違反があります。 ご協力いただければ幸いです。どうもありがとう。あなたのコードで

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

    /* these arrays are just used to give the parameters to 'insert', 
     to create the 'people' array 
    */ 

    #define HOW_MANY 7 
    char *names[HOW_MANY]= {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim", 
        "Harriet"}; 
    int ages[HOW_MANY]= {22, 24, 106, 6, 18, 32, 24}; 

    /* declare your struct for a person here */ 
    struct person { 
     char *name; 
     int age; 
    }; 

    static void insert(struct person **arr, char *name, int age) 
    { 
     //initialise nextfreeplace 
     static int nextfreeplace = 0; 
     //allocate memory 
     arr[nextfreeplace] = malloc (sizeof(struct person)); 
     /* put name and age into the next free place in the array parameter here */ 
     arr[nextfreeplace]->name = name; 
     arr[nextfreeplace]->age = age; 
     /* modify nextfreeplace here */ 
     nextfreeplace++; 
    } 

    int main(int argc, char **argv) 
    { 

     /* declare the people array here */ 
     struct person *people; 

     for (int i = 0; i < HOW_MANY; i++) 
     { 
     insert (&people, names[i], ages[i]); 
     } 

     /* print the people array here*/ 
     for (int i = 0; i < HOW_MANY; i++) 
     { 
     printf("Name: %s \t Age: %i \n", people[i].name, people[i].age); 
     } 

     return 0; 
    } 
+3

[よくある質問はどうすればよいですか?](https://stackoverflow.com/help/how-to-ask)と[最小限の完全かつ検証可能な例を作成する方法](https:///stackoverflow.com/help/mcve)。 – Rabbid76

+3

コードの画像を投稿せず、コード自体を投稿してください。 –

+0

あなたはどの出力を期待していますか? – alk

答えて

2

、あなたが

#define HOW_MANY 7 
/* ... */ 
struct person { 
    /* ... */ 
}; 

static void insert(struct person **arr/* ... */) { 
    static int nextfreeplace = 0; 
    /* ... */ 
    arr[nextfreeplace] = malloc(sizeof(struct person)); 
    /* ... */ 
    nextfreeplace++; 
} 

int main(int argc, char **argv) { 
    /* ... */ 
    struct person *people; 

    for (int i = 0; i < HOW_MANY; i++) { 
     insert(&people/* ... */); 
    } 
    /* ... */ 
    return 0; 
} 

を持っている問題は、ポインタとしてpeopleという名前の変数を定義することです。次に、そのポインタのアドレスをinsertに渡します。ローカル変数は(通常)スタックに割り当てられるので、insertで行われた割り当ては、その一部を上書きします。

は、あなたが次に

struct person *people; 
struct person *otherpeople; 

があると、あなたはnextfreeplace == 0を持っているとき、あなたは罰金である、arr[0] == *arrに割り当てます。しかし、nextfreeplace == 1の場合はarr[1] == *(arr+1) == otherpeopleに割り当てます。

このタイプのバグをバッファオーバーフローといいます。

このバグを修正するには、struct person *people[HOW_MANY];insert(people/* ... */);を使用する必要があります。

さらに、割り当てられたメモリを解放してください。もう不要なのはfreeです。

+0

こんにちは。あなたのお手伝いをする時間を取ってくれてありがとう。コードは私のユニコースの一部であり、「mallocを呼び出して新しい構造体を作成し、それを指す正しい配列要素を設定するためにinsertを変更する」と言ってきました。私は、メモリを割り当てるために主な関数[HOW_MANY]を使用することは許されていないことを意味していると思います。( –

+0

「[...]と正しい*配列要素を設定しています*そうでなければ、 'person'型の' HOW_MANY'構造体のためにメモリを割り当てる必要があります(つまり 'struct person * people = malloc (HOW_MANY * sizeof(* people)); ')そしてそれぞれを満たすことができますが、ポインタを設定しないと、割り当ては' insert'の外側になります。 – Abrixas2

関連する問題