2016-10-25 26 views
-3

次のプログラムに問題があります。コンパイルしようとすると、クラッシュします。私はそれが挿入機能のどこかのセグメンテーションフォールトだと思うが、私はちょうどどこにあるのか分からない。ここでC malloc構造体実装

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

struct person 
{ 
    char name[40]; 
    unsigned int age; 
    struct person *next; 
}; 

struct person* insert(struct person *people[], char *name, int age) 
{ 
    struct person *ptr; 
    ptr=(struct person *)malloc(sizeof(struct person)); 
    if(ptr==NULL) 
    { 
    printf("error"); 
    return; 
    } 
    //ptr=ptr->next; 
    strcpy(ptr->name,name); 
    ptr->age = age; 
    ptr->next=NULL; 

} 

int main() 
{ 
    struct person *people[HOW_MANY]; 
    for (int i =0; i<HOW_MANY;i++) 
     insert (people, names[i], ages[i]); 

    for(int i=0;i<HOW_MANY;i++) 
    printf("%s %d\n", people[i]->name, people[i]->age); 
    return 0; 
} 
+2

コードをデバッガでシングルステップ実行しましたか?それはどのラインが失敗したかを教えてくれるはずです。私は、 'insert'は' ptr'を 'people'配列に入れないことに注意します。これは私が推測しているのは根本的な問題です。 – cxw

+1

コードに矛盾する目標があります。 'next'メンバを持つと、リンクされた人のリストを表示したいように見えますが、' main() 'に' struct person'ポインタの配列を宣言しています。配列やリンクリストを作成しようとしていますか? – eddiem

+0

構造体ポインタの配列 –

答えて

2

あなたが前方に移動を取得する必要があり、小さな変化です:

void insert(struct person **person_ptr, char *name, int age) 
{      /* ^^^^^^^^^^^^ one person */ 
    struct person *ptr; 
    ... 
    ptr->next=NULL; 
    *person_ptr = ptr; /* send _ptr_ back to the calling code. */ 
} 

int main() 
{ 
    struct person *people[HOW_MANY]; 
    for (int i =0; i<HOW_MANY;i++) 
     insert (&people[i], names[i], ages[i]); 
      /*^ ^^^ Just pass the one person you're interested in */ 
    ... 
} 

説明:**person_ptrはポインタ(&people[i])のアドレスを取得します。その後、*person_ptr=...はその値を変更します。したがって、効果はinsert()(本質的に)*&people[i]=ptr;、つまりpeople[i]=ptr;となります。 &*が必要なのは、Cが引数ではなく値で引数を渡すからです。

コードには他にもいくつか問題があることに注意してください。

  • メモリが不足している場合は、insert()の呼び出し元には認識されません。 "error"の印刷物があるのでそれを知っていますが、呼び出し側はそれを知っている必要があります。
  • @eddiemが指摘しているように、配列のみを使用している場合は、nextは必要ありません。
  • insert()は、struct person*を返すと宣言されていますが、その戻り値は決して割り当てられず、使用されません。 insert()void insert()または(成功または失敗を示す)bool insert()となります。
+0

'return(ptr);'ははるかに簡単です。 –

+0

@AndrewHenle合意。私はOPの論理にできるだけ近づけようとしていたので、 '**'。 – cxw

+0

@cxw関数は値を返すか、 'void 'と宣言する必要があります戻り値 –

関連する問題