2016-12-08 2 views
1
typedef struct { 
    List *table; 
    unsigned int size; 
} HashTable; 

typedef struct node { 
    Data data; 
    struct node *next; 
} NODE; 

struct listptrs { 
    NODE *tail; 
    NODE *head; 
    NODE *prev; 
    NODE *current; 
}; 

typedef struct listptrs List; 

HashTable createHashTable(unsigned int size) { 
    //HashTable htable = { 0 }; 
    //return htable; 

    int i; 
    HashTable *htable = NULL; 
    htable = malloc(sizeof(HashTable) * size); 

    for (i = 0; i < size; i++) { 
     htable[i].table = malloc(sizeof(List)); 
     htable[i].table->current = NULL; 
     htable[i].table->head = NULL; 
     htable[i].table->prev = NULL; 
     htable[i].table->tail = NULL; 
     htable[i].size = size; 
    } 
    return *htable;//??? 
} 

Puis, en principal:Retour d'un tableau de structures allouées dynamiquement à partir d'une fonction dans C?

HashTable htable = createHashTable(tableSize); 

htable n'agit pas comme un tableau du tout. Des idées comment le résoudre sans changer aucune valeur de retour de la fonction et des arguments pour les fonctions? Cela fait partie d'une affectation scolaire et seul le contenu de la fonction createHashTable peut être modifié. Le reste du programme n'est pas ici parce que ce n'est pas pertinent à la question.

+2

Peut-être que vous devriez retourner un pointeur * * à 'HashTable' de la fonction? À l'heure actuelle, vous ne renvoyez que le premier élément du tableau que vous avez créé (et vous avez une fuite de mémoire). Ou changez l'alias de type 'HashTable' en pointeur (ce que je ne recommande vraiment pas). –

Répondre

2

Vous voulez peut-être ceci:

HashTable *createHashTable(unsigned int size) 
{ 
    //HashTable htable = { 0 }; 
    //return htable; 

    int i; 
    HashTable* htable = NULL; 
    htable = malloc(sizeof(HashTable)* size); 
    for(i=0; i<size; i++) 
    { 
     htable[i].table = malloc(sizeof(List)); 
     htable[i].table->current = NULL; 
     htable[i].table->head = NULL; 
     htable[i].table->prev = NULL; 
     htable[i].table->tail = NULL; 
     htable[i].size = size; 
    } 

    return htable; 
} 

Comme vous allouez le tableau dynamique, vous pouvez simplement renvoyer le pointeur nouvellement alloué. Renvoyer un HashTable comme vous essayiez ne fait pas de sens, parce que cela vous permettrait de retourner un seul HashTable, mais vous voulez retourner un tableau complet de HashTable s.

Utilisation:

Au lieu de:

HashTable htable = createHashTable(tableSize); 

Vous devez ceci:

HashTable *htable = createHashTable(100); 
... 
... // when done you need to delete the hashtable 
deleteHashTable(htable); 

Le deleteHashTable est encore à écrire, il faut essentiellement free le pointeur table et à free la table elle-même.

Maintenant, si vous êtes autorisé vraiment changer seul le contenu de la fonction createHashTable mais pas la signature de la fonction, votre question n'a pas de sens, car avec la signature de la fonction HashTable createHashTable(unsigned int size) vous ne pouvez revenir unHashTable mais pas tableau de HashTable s.

Mais alors peut-être que vous voulez réellement ceci:

HashTable createHashTable(unsigned int size) 
{ 
    HashTable htable = { 0 }; 

    int i; 
    for(i=0; i<size; i++) 
    { 
     htable[i].table = malloc(sizeof(List)); 
     htable[i].table->current = NULL; 
     htable[i].table->head = NULL; 
     htable[i].table->prev = NULL; 
     htable[i].table->tail = NULL; 
     htable[i].size = size; 
    } 

    return htable; 
} 

Avec cette deuxième solution, vous avez encore besoin d'écrire la fonction qui supprime la table de hachage.

+0

L'attribution d'un tableau de 'HashTable' n'a pas vraiment de sens. – chqrlie

0

La table de hachage lui-même est pas censé « se comporter comme un tableau », et ceci:

return *htable; 

n'a pas de sens, elle renvoie le premier élément de votre tableau de tables de hachage.

Vous n'êtes pas censé créer un tableau de tables de hachage bien, vous êtes censé créer une seule table de hachage, qui peut contenir un tableau (qui est la table). Il a aussi une variable de taille par exemple, donc il y a plus que le tableau lui-même dans la table de hachage.

Vous devriez faire

htable = malloc(sizeof *htable); 

d'attribuer une seule instance, puis initialisez que nécessaire et le retourner.

0

Il semble y avoir une certaine confusion ici: createHashTable() n'est pas censé allouer un tableau de tables de hachage, mais une structure HashTable avec une taille initiale pour ses membres table intégré.

En outre, il est de pratique non standard de retourner la structure en valeur. Vous devez à la place renvoyer le pointeur sur le HashTable alloué ou éventuellement prendre un pointeur vers la structure HashTable allouée dynamiquement ou statiquement par l'appelant et l'initialiser.

est ici une version modifiée du code pour cette approche:

#include <stdlib.h> 

typedef struct { 
    List *table; 
    unsigned int size; 
} HashTable; 

typedef struct node { 
    Data data; 
    struct node *next; 
} NODE; 

struct listptrs { 
    NODE *tail; 
    NODE *head; 
    NODE *prev; 
    NODE *current; 
}; 

typedef struct listptrs List; 

HashTable *createHashTable(unsigned int size) { 
    HashTable *htable = malloc(sizeof(*htable)); 

    if (htable == NULL) 
     return NULL; 
    } 
    htable->size = size; 
    htable->table = NULL; 
    if (size == 0) { 
     return htable; 
    } 
    htable->table = malloc(sizeof(*htable->table) * size); 
    if (htable->table == NULL) { 
     free(htable); 
     return NULL; 
    } 
    for (unsigned int i = 0; i < size; i++) { 
     htable->table[i].head = NULL; 
     htable->table[i].tail = NULL; 
     htable->table[i].prev = NULL; 
     htable->table[i].current = NULL; 
    } 
    return htable; 
} 

Appel de main():

HashTable *htable = createHashTable(100);