Non. Vos types ne correspondent pas.
Essayez-vous d'allouer une table d'entrées de hachage (à savoir le type de table[i]
est struct hash_entry
), une table de pointeurs à hash_entries (à savoir le type de table[i]
est struct hash_entry *
), ou autre chose? Basé sur la lecture de votre code, je suppose le premier cas, mais laissez-moi savoir si c'est faux.
En supposant que vous allouer dynamiquement une table de struct hash_entry
, votre déclaration de la table dans l'appelant doit être
struct hash_entry *table; // 1 *, no array dimension
la fonction doit être appelée comme
int result = maketable(&table, number_of_elements);
et défini as
int maketable (struct hash_entry **table, size_t size)
{
int r = 0;
// sizeof **table == sizeof (struct hash_entry)
*table = malloc(sizeof **table * size);
// *ALWAYS* check the result of malloc()
if (*table)
{
size_t i;
for (i = 0; i < size; i++)
memset(&(*table)[i], 0, sizeof (*table)[i]);
r = 1;
}
return r;
}
Un couple de choses à signaler. Tout d'abord, ne pas diffuser le résultat de malloc()
. A partir de C89, vous n'avez pas besoin de le faire, et la distribution supprimera un diagnostic si vous oubliez d'inclure stdlib.h ou si vous n'avez pas de prototype pour malloc()
dans la portée. Deuxièmement, vous pouvez utiliser l'opérateur sizeof
sur les objets au lieu des types. Cela peut aider à réduire certains maux de tête de maintenance (c'est-à-dire, si vous modifiez le type de table
dans la liste de paramètres, vous n'avez pas besoin de modifier les appels sizeof
en même temps).
Enfin, notez que l'adresse de la table est en cours de transmission à la fonction; puisque nous essayons d'écrire sur une valeur de pointeur, nous devons passer un pointeur vers ce pointeur.
Si vous essayez de créer une table de pointeurs vers struct hash_entry
, le code est essentiellement le même, juste un niveau supplémentaire d'indirection:
votre déclaration de la table dans l'appelant doit être
struct hash_entry **table; // 2 *, no array dimension
la fonction doit être appelée comme
int result = maketable(&table, number_of_elements);
et défini comme
int maketable (struct hash_entry ***table, size_t size)
{
int r = 0;
// sizeof **table == sizeof (struct hash_entry *)
*table = malloc(sizeof **table * size);
// *ALWAYS* check the result of malloc()
if (*table)
{
size_t i;
for (i = 0; i < size; i++)
(*table)[i] = NULL;
r = 1;
}
return r;
}
EDIT Il y avait un bug dans les maketable
exemples; table
doit être déréférencé avant d'appliquer l'indice, c'est-à-dire (*table)[i]
. Nous appliquons l'indice à ce que table
pointe à, pas le pointeur de table lui-même.
Désolé pour toute confusion.
Je ne comprends pas. Vous allouez de la mémoire sur la pile pour la variable, puis réallouez quelque chose dans la fonction? - En outre, 'table' est une variable locale. Vous allouer quelque chose et l'affecter à 'table' qui disparaîtra lorsque la fonction revient, provoquant une fuite de mémoire. –
Le problème est que je ne comprends pas non plus. Est-ce que ma déclaration de struct hash_entry ** table [taille] alloue implicitement la mémoire pour moi? Dans ce cas, je dois encore malloc pour les hash_entrys eux-mêmes quand je les déclare, non? –
La déclaration alloue de la mémoire pour un tableau avec la taille 'size' de pointeurs vers des pointeurs de type' hash_entry' sur la pile. Il n'alloue pas de mémoire pour les emplacements vers lesquels les éléments du tableau vont pointer. –