2017-07-12 9 views
3

Ich arbeite an dem Erstellen einer Hash-Tabellenimplementierung für eine Zuordnung. Ich habe meine Hash-Tabelle als Struktur wie folgt definiert:C-Struktur mit Zeiger auf Zeiger initialisieren

typedef struct hashtable { 
    int size; 
    int entries; 
    int table*; // pointer to table. Each entry will point to linked list 
       // of key-value nodes 
} hashtable; 

Ich habe die Hash-Tabelle Struktur in einem Verfahren unter Verwendung Doppel Zeiger zu initialisieren, zB:

void init(hashtable** ht) { 
... 
} 

ich eine grundlegende Implementierung geschrieben haben, unter:

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

typedef struct hashtable { 
    int size; 
    int entries; 
    int table*; // pointer to table. Each entry will point to linked list 
       // of key-value nodes 
} hashtable; 

void init(hashtable**); 

void init(hashtable** ht) { 
    *ht = (hashtable *) malloc(sizeof(hashtable)); 
    *ht->size = 3; 
} 

int main(){ 

    hashtable *t = NULL; 
    init(&t); 

    printf("t.size: %i", t->size); 
} 

aber ich erhalte den folgenden Compiler-Fehler:

ll.c:19:8: error: member reference base type 'hashtable *' (aka 'struct hashtable *') is not a 
     structure or union 
    *ht->size = 3; 
    ~~^ ~~~~ 
1 error generated. 

So bin ich verwirrt durch folgende: 1. Ich bin mir nicht sicher, wie man eine neue Struktur in der Init-Funktion erstellt, wenn ein Zeiger auf Zeiger übergeben wird. 2. Wie ändere ich nach dem Zuweisen der Struktur die Strukturelementattribute?

+5

diese '* HT-> size = 3;' -> '(* ht) -> size = 3;' ' –

+0

int Tabelle *; '??? – AnT

Antwort

2

Dies ist nur ein Operator Vorrang-Problem.

Der Compiler verarbeitet -> vor dem *. Daher versucht es, auf das Size-Member von struct hashtable ** zuzugreifen, was nicht möglich ist.

Der Code wird kompiliert, wenn Sie * ht-> Größe mit (* ht) -> Größe austauschen.

+0

Danke, dass das Problem behoben wurde. –

1

Das Problem ist, dass

-> höhere Priorität als * in C hat, wie Sie von here

mit Vorrangregeln *ht->size übersetzt * (HT-> Größe) zu sehen. Das sollte den Grund klar machen, warum Sie den Fehler erhalten. Ein anderer Weg, um es zu sehen ist

*(ht->size)=(*(*ht).size) 

Fix diese unter Verwendung von Klammern wie folgt: (*ht)->size

Es gibt ein weiteres Problem bei der Definition von hashtable: int table*; wird nicht kompiliert. Verwenden Sie stattdessen int *table;, um eine pointer to int zu deklarieren?

2

Sie haben zwei Fehler im Code:

  1. int table* ->int *table - Deklarieren Zeiger

  2. * HT-> Größe integer ->(*ht)->size - Imp Klammern zu setzen, wenn Sie sind nicht sicher von

+0

danke, der tisch * war typo. –

1

Das ist ein guter Anfang, und andere haben die primären Probleme in Ihrem Code angesprochen. Allerdings würde ich vorschlagen, eine kleine zwicken:

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

typedef struct hashtable { 
    int size; 
    int entries; 
    int table*; // pointer to table. Each entry will point to linked list 
       // of key-value nodes 
} hashtable; 


// note: freeing the hashtable is a caller responsibility! 
hashtable *new_hashtable() { 
    hashtable *ht = malloc(sizeof(hashtable)); 
    ht->size = 3; // since ht is only a single pointer, no need for (*ht)->foo 

    return ht; 
} 

int main(){ 

    hashtable *ht = new_hashtable(); 

    printf("ht.size: %i", ht->size); 

    free(ht); 
} 
+0

schätzen Sie die Rückmeldung über die Rückgabe des Zeigers. Ich bin hier durch meine Aufgabenspezifikationen eingeschränkt. –

+0

Oh, ich verstehe. Bedenken Sie das für die Zukunft. Dieser Weg ist sicherer, weil Sie niemals 'NULL' zuweisen sollen. Sie erhalten den Zeiger direkt von der Funktion, ohne zu vergessen, 'init' zu nennen. – Alexander

0

Vielen Dank für die schnelle Antwort.Für zukünftige Referenz, hier ein kurzes Update des ursprünglichen Codes mit Lösungen:

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

typedef struct hashtable { 
    int size;  // size of hash table 
    int entries; // number of slots allocated in table 
    int *table; /* pointer to table. Each entry will point to linked list 
        of key-value nodes */ 
} hashtable; 

void init(hashtable**); 

void init(hashtable** ht) { 
    *ht = (hashtable *) malloc(sizeof(hashtable)); 
    (*ht)->entries = 0; 
    (*ht)->size = 3; //replace this with better init size, ideally a prime number 
    (*ht)->table = malloc((*ht)->size * sizeof(int)); 
} 

int main(){ 

    hashtable *t = NULL; 
    init(&t); 
    t->table[2] = 3; 

    printf("t.size: %i \n", t->size); 
    printf("t.arr:[2] %i \n", t->table[2]); 
    free(t); 
} 
+0

Wahrscheinlich möchten Sie 'calloc' verwenden – Alexander