2017-01-09 13 views
0

問題があり、何をすべきかわからない。ポインタ配列に構造体ポインタを追加する

生徒の配列に「新生児」を挿入しようとしています。配列には、作成された構造体へのポインタが含まれています。誰かがエラーを見つけることができますか?これは、学生構造体を配列に追加しますが、特に印刷はしません。

誰かが私を助けることができたら、本当に役に立ちます。 :) PS:あなたはちょうどコードをコピーすることができます。

はここに私のコードです:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define MAX_HASH 10 
typedef struct student 
{ 
    unsigned int matnr; 
    char *name; 
    struct student *next_student; 
} Student; 

Student **hash_tabelle[MAX_HASH]; 

void insert_student (unsigned int matnr, char *name) 
{ 
    Student *neuer_student = malloc(sizeof(Student)); 
    neuer_student->name = malloc(sizeof(*name)+1); 
    neuer_student->matnr = matnr; 
    strcpy(neuer_student->name, name); 
    neuer_student->next_student = NULL; 

    // Index im Hash-Array ermitteln 
    int hash_index = matnr % 10; 

    if(hash_tabelle[hash_index] == NULL) 
    { 
     neuer_student->next_student = hash_tabelle[hash_index]; 
     hash_tabelle[hash_index] = neuer_student; 
    } 
    else 
    {  
     while(*hash_tabelle[hash_index] != NULL && (((*hash_tabelle[hash_index])->matnr - neuer_student->matnr) <= 0)) 
      hash_tabelle[hash_index] = &(*hash_tabelle[hash_index])->next_student; 
     neuer_student->next_student = *hash_tabelle[hash_index]; 
     *hash_tabelle[hash_index] = neuer_student; 
    } 
} 

void print_hash_tabelle() 
{ 
    for(int i = 0; i != MAX_HASH - 1; i++){ 
     printf("%d)\t", i); 

     hash_tabelle[i] = &(*hash_tabelle[i])->next_student; 

     for(; hash_tabelle[i] != NULL; hash_tabelle[i] = &(*hash_tabelle[i])->next_student){ 
      printf("%s (%d)", (&(*hash_tabelle[i])->name), (&(*hash_tabelle[i])->matnr)); 
     } 
     printf("\t"); 
    } 
} 

int main() 
{ 
    unsigned int matnr; 
    char name[100]; 

    do 
    { 
     printf("Matrikelnummer:\t"); 
     scanf("%d", &matnr); 
     fflush(stdin); 
     getchar(); // um das \n aus dem Puffer zu kriegen und rauszuschmeißen 
     printf("Name:\t\t"); 
     fgets(name, 30, stdin); 
     insert_student(matnr, name); 
    } 
    while (matnr != 0); 

    print_hash_tabelle(); 

    return 0; 
} 
+1

"のdoesntの仕事は、" 適切な説明ではありません。 *どのように動作しませんか?代わりに何をやろうとしているのですか?あなたは、デバッガを使うなどの基本的なデバッグを自分でやったことがありますか? – kaylum

+3

'malloc(sizeof(* name)+1);' - それは正確に** 2 **文字を割り当てます。 *常に*。 'sizeof'はそれがあなたが思うことはしません。 ['strlen'](http://en.cppreference.com/w/c/string/byte/strlen)を参照してください。 – WhozCraig

+0

'Student ** hash_tabelle [MAX_HASH];' - > 'Student * hash_tabelle [MAX_HASH];' – BLUEPIXY

答えて

1

あるので、単純なハッシュテーブルを使用して...リンクリストポインタの固定サイズの配列のためのデリファレンスを使用する必要はありません。

ステップ1 - ハッシュテーブルは、リンクリストポインタの配列です。

@BLUEPIXYの通り:

Student *hash_tabelle[MAX_HASH]; 

ステップ2 - NULLに各項目を初期化し、各リンクされたリストを割り当て、無料するが。

そうでない場合は、if(hash_tabelle[hash_index] == NULL)は機能insert_student()で 振る舞いを定義されていません。

void hash_init() 
{ 
    for(int i=0;i<MAX_HASH;i++) { 
     hash_tabelle[MAX_HASH]=NULL; 
    } 
} 

ステップ3からinsert_student()char *nameを格納するのに十分なチャーを割り当てます。

@ WhozCraigと同様に、strlen()を使用してください。

void insert_student (unsigned int matnr, char *name) 
{ 
    Student *neuer_student = malloc(sizeof(Student)); 
    neuer_student->name = malloc(strlen(name)+1); 
    neuer_student->matnr = matnr; 
    strcpy(neuer_student->name, name); 
    neuer_student->next_student = NULL; 

ステップ4からhash_tabelle[](関数insert_student()

警告にneuer_studentを追加:インデックスが配列 のサイズに含まれなければならない[0..MAX_HASH [ 。 (MAX_HASHの代わりに10を使用するとバグになる可能性があります)。

hash_tabelle[hash_index]はNULL、簡単な店舗 neuer_studentがある

int hash_index = matnr % MAX_HASH; 
neuer_student->next_studentを変更する必要はありません。エルス

if(hash_tabelle[hash_index] == NULL) 
{ 
    hash_tabelle[hash_index] = neuer_student; 
} 

終わり neuer_studentを保存するためにhash_tabelle[hash_index]のリンクリストを探ります。

else 
{ 
    Student *tmp; 

    tmp = hash_tabelle[hash_index]; 
    while (tmp->next_student!=NULL) { 
     tmp = tmp->next_student; 
    } 
    tmp->next_student = neuer_student; 
} 

ステップ5 - ハッシュテーブルのすべての項目を印刷する(関数print_hash_tabelle()

各リンクリストのポインタを探索するために、同じ方法を再利用。

警告:0からステップ6MAX_HASH-1

void print_hash_tabelle() 
{ 
    for(int i = 0; i < MAX_HASH; i++){ // ERR != MAX_HASH - 1; i++){ 
     printf("%d)\t", i); 
     Student *tmp = hash_tabelle[i]; 
     while (tmp!=NULL) { 
      printf("%s (%d)", tmp->name, tmp->matnr); 
      tmp = tmp->next_student; 
     } 
     printf("\n"); 
    } 
} 

にすべてのアイテムを探索 - hash_tabelle[]の各項目のメモリを解放します。

  1. 割り当てられた文字列free(tmp->name);を無料。
  2. すべてhash_free()への呼び出しを追加することを除いてmain()中(変化なしだリンクリストの最後

まで、現在の学生hash_tabelle[i] = tmp->next_student;

  • 無料にfree(tmp);
  • 繰り返しを割り当てられた学生を削除します最後に)。このような

    void hash_free() 
    { 
        for(int i=0;i<MAX_HASH;i++) { 
         Student *tmp = hash_tabelle[i]; 
         while (tmp!=NULL) { 
          free(tmp->name); 
          hash_tabelle[i] = tmp->next_student; 
          free(tmp); 
          tmp = hash_tabelle[i]; 
         } 
        } 
    } 
    
  • 0

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    
    #define MAX_HASH 10 
    
    typedef struct student { 
        unsigned int matnr; 
        char *name; 
        struct student *next_student; 
    } Student; 
    
    Student *hash_tabelle[MAX_HASH]; 
    
    void insert_student (unsigned int matnr, char *name){ 
        Student *neuer_student = malloc(sizeof(Student)); 
        neuer_student->name = malloc(strlen(name)+1); 
        strcpy(neuer_student->name, name); 
        neuer_student->matnr = matnr; 
        //neuer_student->next_student = NULL; 
    
        int hash_index = matnr % MAX_HASH; 
        Student head = { .next_student = hash_tabelle[hash_index] }; 
        Student *prev = &head, *curr = head.next_student; 
        while(curr != NULL && curr->matnr <= neuer_student->matnr){ 
         prev = curr; 
         curr = curr->next_student; 
        } 
        neuer_student->next_student = curr; 
        prev->next_student = neuer_student; 
        hash_tabelle[hash_index] = head.next_student; 
    } 
    
    void print_hash_tabelle(void){ 
        for(int i = 0; i < MAX_HASH; i++){ 
         printf("%d)\t", i); 
         for(Student *p = hash_tabelle[i]; p; p = p->next_student){ 
          printf("%s (%d)\t", p->name, p->matnr); 
         } 
         printf("\n"); 
        } 
    } 
    
    void free_hash_tabelle(void){ 
        for(int i = 0; i < MAX_HASH; i++){ 
         Student *p = hash_tabelle[i]; 
         while(p){ 
          Student *temp = p->next_student; 
          free(p->name); 
          free(p); 
          p = temp; 
         } 
        } 
    } 
    
    int main(void){ 
        int matnr = -1;//for %d of scanf 
        char name[100]; 
    
        while(1){ 
         printf("Matrikelnummer(-1 for end input): ");fflush(stdout); 
         scanf("%d", &matnr); 
         if(matnr < 0) 
          break; 
         while(getchar() != '\n'); 
         printf("Name: ");fflush(stdout); 
         fgets(name, sizeof name, stdin); 
         name[strcspn(name, "\n")] = 0; 
         insert_student(matnr, name); 
        } 
    
        print_hash_tabelle(); 
        free_hash_tabelle(); 
    
        return 0; 
    } 
    
    関連する問題