2013-02-28 2 views
2

J'ai cette fonction "charger" où je lis les mots d'un dictionnaire et les mets dans une table de hachage de listes chaînées. Lorsque j'essaie de lire une ligne et de l'enregistrer dans mon nouveau_node-> texte, le compilateur renvoie SEGMENTATION FAULT et je ne sais pas pourquoi. L'erreur apparait quand j'utilise strncpy.SEGMENTATION FAULT dans strncpy - charger du dictionnaire

#define HASHTABLE_SIZE 76801 


typedef struct node 
{ 
     char text[LENGTH+1]; 
     //char* text; 
     //link to the next word 
     struct node* next_word; 
} 
node; 


    node* hashtable[HASHTABLE_SIZE]; 

    bool load(const char* dictionary) 
    { 
     FILE* file = fopen(dictionary,"r"); 
     unsigned long index = 0; 
     char str[LENGTH+1]; 

     if(file == NULL) 
     { 
      printf("Error opening file!"); 
      return false; 
     } 

     while(! feof(file)) 
     { 
      node * new_node = malloc(sizeof(node)+1000); 


      while(fscanf(file,"%s",str) > 0) 
      { 
       printf("The word is %s",str); 
       strncpy(new_node->text,str,LENGTH+1); 
       //strcpy(new_node->text,str); 

       new_node->next_word = NULL; 
       index = hash((unsigned char*)new_node->text); 

       if(hashtable[index] == NULL) 
       { 
        hashtable[index] = new_node; 
       } 
       else 
       { 
        new_node->next_word = hashtable[index]; 
        hashtable[index] = new_node; 
       } 

       n_words++; 

      } 
      //free(new_node); 



     } 
     fclose(file); 
     loaded = true; 

     return true;  
    } 
+3

Vous devez être prudent avec 'strncpy' car il se peut qu'il ne termine pas la chaîne. Et pourquoi allouez-vous 1000 octets supplémentaires pour le noeud? –

+2

En outre, utilisez un débogueur pour savoir où le crash se produit. Il vous permettra également de voir la pile d'appel pour voir comment vous avez fini là où se trouve l'accident, et vous permettra d'examiner les variables pour vous aider à comprendre pourquoi il a peut-être planté. –

+0

'node * new_node = malloc (sizeof (node) +1000);' Quoi? Pourquoi les 1000 octets supplémentaires? –

Répondre

5

Regardons votre code ligne par ligne, allons-nous?

while(! feof(file)) 
    { 

Ce n'est pas la bonne façon d'utiliser feof - vérifier le poste Why is “while (!feof (file))” always wrong? ici sur StackOverflow.

 node * new_node = malloc(sizeof(node)+1000); 

Hmm, ok. Nous allouons de l'espace pour un noeud et 1000 octets. C'est un peu bizarre, mais bon ... la RAM est bon marché.

 while(fscanf(file,"%s",str) > 0) 
     { 

Uhm ... une autre boucle? OK ...

  printf("The word is %s",str); 
      strncpy(new_node->text,str,LENGTH+1); 
      //strcpy(new_node->text,str); 

      new_node->next_word = NULL; 
      index = hash((unsigned char*)new_node->text); 

Hey! Attendez une seconde ... dans cette deuxième boucle, nous continuons à plusieurs reprises ... new_node écraser

  if(hashtable[index] == NULL) 
      { 
       hashtable[index] = new_node; 
      } 
      else 
      { 
       new_node->next_word = hashtable[index]; 
       hashtable[index] = new_node; 
      } 

On suppose une seconde que les deux mots de hachage au même seau:

OK, donc la première fois à travers la boucle, hashtable[index] pointera sur NULL et sera défini pour pointer sur new_node.

La deuxième fois à travers la boucle, hashtable[index] n'est pas NULL si new_node seront faits pour indiquer quelles que soient hashtable[index] points (indice: new_node) et hashtable[index] seront faits pour pointer vers new_node).

Savez-vous ce qu'est un ouroboros?

Supposons maintenant qu'ils ne hachent pas le même seau:

Un des seaux contient maintenant des informations erronées. Si vous ajoutez d'abord "salut" dans le compartiment 1 et "au revoir" dans le compartiment 2, quand vous essayez de traverser le compartiment 1, vous pouvez (seulement parce que le code de liaison est cassé) trouver "au revoir" qui n'appartient pas au compartiment 1 tout.

Vous devriez attribuer un nouveau nœud pour chaque mot que vous ajoutez. Ne réutilisez pas le même noeud.

+1

Une boucle en utilisant 'feof' comme ça est presque toujours faux. Ce programme est l'un de ces cas. –

+0

Vous êtes, bien sûr, correct. J'ai totalement raté ça. Post édité. –