2011-11-14 4 views
0

Ceci est beaucoup de code mais je suis à la fin ici essayant de comprendre pourquoi cela ne fonctionne pas.c tableau de structures

C'est le code que je suis en cours d'exécution:

struct dict { 
    struct word **tbl; 
    int (*hash_fcn)(struct word*); 
    void (*add_fcn)(struct word*); 
    void (*remove_fcn)(struct word*); 
    void (*toString_fcn)(struct word*); 
}; 

struct word { 
    char *s; 
    struct word *next; 
}; 

cela fait partie de la fonction principale:

hashtbl=malloc(sizeof(struct dict)); 
    //hashtbl->tbl=malloc(sizeof(struct word*)*256); 
    int i; 
    for(i=0;i<256;i++) 
    { 
    hashtbl->tbl[i] = malloc(sizeof(struct word)); 
    hashtbl->tbl[i] = NULL; 
    //hashtbl->tbl[i]=NULL; 
    } 
    hashtbl->add_fcn=&add_word; 
    hashtbl->remove_fcn=&remove_word; 
    hashtbl->hash_fcn=&hash_function; 
    hashtbl->toString_fcn=&toString; 

    FILE *p; 
    p = fopen("a.txt", "r"); 
    if(p == NULL) { printf("ERROR!\n"); return 0; } 
    char line[MAXBYTES]; 
    while(fgets(line, MAXBYTES, p)) 
    { 
     char *token = strtok(line, " "); 
     while(token != NULL) 
    { 
     struct word *words = malloc(sizeof(struct word)); 
     words->s = token; 
     words->next=NULL; 
     trim(words); 
     hashtbl->add_fcn(words); 
     token = strtok(NULL, " "); 

     printf("....\n"); 
     hashtbl->toString_fcn(NULL); 
     printf("....\n\n"); 

     } 
     free(token); 
    } 

Voici deux fonctions utilisées (à cordes qu'afficher dehors)

void add_word(struct word *insert) 
{ 
    if(strcmp(insert->s, "\n") == 0) {return;} 

    int hash = hashtbl->hash_fcn(insert); 

    if(hash==0) { return; } 
    struct word *word = hashtbl->tbl[hash]; 
    if(word==NULL) 
    { 
    struct word *newword = malloc(sizeof(struct word)); 
    newword->s=insert->s; 
    newword->next=NULL; 
    hashtbl->tbl[hash]=newword; 

    printf("() %d %s \n", hash, hashtbl->tbl[hash]->s); 
    } 
    else 
    { 
    struct word *tp = word; 
    while(word->next != NULL) 
     word=word->next; 
    struct word *newword = malloc(sizeof(struct word)); 
    newword->s=insert->s; 
    newword->next=NULL; 
    word->next=newword; 
    hashtbl->tbl[hash]=tp; 
    } 
} 

int hash_function(struct word *string) 
{ 
    char *firstletter = string->s; 
    char c = *firstletter; 
    int ascii = (int)c; 
    return ascii; 
} 

a.txt est

cat 
dog 
mouse 

et imprime les éléments suivants:

() 99 cat 
.... 
99 : cat 
.... 

() 100 dog 
.... 
99 : dog 
100 : dog 
.... 

() 109 mouse 
.... 
99 : mouse 
100 : mouse 
109 : mouse 
.... 

il doit être imprimé sur

99:cat 
100:dog 
109:mouse 

grâce

+0

duplication possible de [tableau de double pointeur c] (http: // stackoverflow.com/questions/8116740/c-double-pointer-array) --- à la lumière de "ne fonctionne pas" étant la seule description du problème, je suis tenté de dire que le PO devrait simplement communiquer plus dans sa question précédente à résoudre le problème. –

+0

Avez-vous exécuté un débogueur sur ce programme? – Simon

+0

Indice: Consultez la documentation de 'strtok()' et assurez-vous que vous comprenez exactement à qui appartient la mémoire pointée par la valeur de retour, et comment vous utilisez actuellement cette valeur. – cbranch

Répondre

2

Vous avez beaucoup de problèmes ici.

Première:

hashtbl=malloc(sizeof(struct dict)); 
//hashtbl->tbl=malloc(sizeof(struct word*)*256); 

Vous devez supprimer cette ligne, car sans elle, vous n'allouez pas le tableau de pointeurs struct dans hashtbl->tbl, et laissez non initialisée. Cela va probablement provoquer une erreur de segmentation telle quelle.

suivant:

for(i=0;i<256;i++) 
{ 
    hashtbl->tbl[i] = malloc(sizeof(struct word)); 
    hashtbl->tbl[i] = NULL; 
    //hashtbl->tbl[i]=NULL; 
} 

Ceci est une fuite de mémoire. Vous attribuez un struct word à chaque élément de hashtbl->tbl, mais en écrasant le pointeur avec NULL. Vous perdez donc toute la mémoire allouée et laissez chaque élément de tableau à NULL. Débarrassez-vous du malloc() et réglez-les sur NULL, car vous allouerez les structures plus tard lorsque vous ajouterez un mot.

Dans cette partie:

hashtbl->add_fcn=&add_word; 
hashtbl->remove_fcn=&remove_word; 
hashtbl->hash_fcn=&hash_function; 
hashtbl->toString_fcn=&toString; 

... la & ne sont pas nécessaires - les noms de fonctions sans parenthèses sont assez bonnes. Tant que les parenthèses sont omises, elles seront interprétées comme l'adresse de la fonction et non comme un appel de fonction.

Et puis ici:

char *token = strtok(line, " "); 
    while(token != NULL) 
    { 
     struct word *words = malloc(sizeof(struct word)); 
     words->s = token; 

... le char * retourné par strtok() les points généralement dans la chaîne que vous traitez, à savoir dans le tampon que vous lisez les lignes dans. Il ne restera pas intact tant que vous continuerez le traitement du fichier. Vous devez faire une copie de la chaîne, pas seulement sauvegarder le pointeur.

free(token); 

... êtes-vous sûr de vouloir le libérer?

+0

Merci! Le problème était principalement le strtok et j'ai utilisé strcpy au lieu de pointer vers lui. Résolu mon problème. – Kamran224

Questions connexes