2011-05-01 3 views
3

J'écris une application C++ pour faire une recherche de mots dans une grande base de données de paroles de chansons. pour commencer, je prends chaque mot et de le mettre dans un struct mot qui ressemble à ceci:La valeur stockée disparaît lors de la définition d'un pointeur de structure à null en C++

struct Word{ 
    char* clean; 
    int size; 
    int position; 
    SongId id; 
    Word* same; 
    Word* diff; 
}; 

J'ai une fonction « makeNode » qui effectue les opérations suivantes:

  1. prend chaque mot
  2. crée une nouvelle struct Word et ajoute le mot à lui
  3. crée un mot * de nœud appelé qui pointe vers le nouveau mot
  4. stocke le pointeur dans une table de hachage.

Dans ma fonction makeNode, je règle node-> clean sur mon mot "clean". Je peux imprimer le mot en cout'ing node-> clean. Mais quand je mets node-> same à NULL, je perds node-> clean. Je ne perds pas de nœud-> position ou nœud-> taille. Si je supprime la ligne où j'affecte node-> same à NULL, je ne perds pas node-> clean.

char* clean = cleanse(word); 
Word* node = new Word; 
node->size = strlen(word); 
node->clean = clean; 
cout<<"MADE NODE FOR "<<node->clean<<endl; 
node->position = position; 
cout<<"4 node clean: "<<node->clean<<endl; 
node->id = id; 
cout<<"5 node clean: "<<node->clean<<endl; 
node->same = NULL; 
cout<<"6 node clean: "<<node->clean<<endl; 
cout<<"node position: "<<node->position<<endl; 
cout<<"node size: "<<node->size<<endl; 
node->diff = NULL; 

donne le résultat suivant:

MADE NODE FOR again 
4 node clean: again 
5 node clean: again 
6 node clean: 
node position: 1739 
node size: 6 
0 node clean: 
1 node clean: 
3 node clean: 

Quelqu'un peut-il me aider à franchir cette erreur? Si vous avez besoin de plus d'info laissez-moi savoir. Merci d'avance!

EDIT: voici la fonction de nettoyage.

char* SongSearch::cleanse(char* dirty) 
{ 

string clean; 
int iter = 0; 
while (!isalnum(dirty[iter])) 
{ 
    iter++; 
} 
while(dirty[iter]!='\0') 
{ 
    clean += dirty[iter]; 
    iter++; 
} 

int backiter = clean.length() - 1; 
while(!isalnum(clean[backiter])) 
{ 
    clean.erase(backiter, 1); 
    backiter--; 
} 


char c; 
    for (int i = 0; i<clean.length(); i++) 
{ 
    c = tolower(clean[i]); 
    clean[i] = c; 
} 

char* toReturn = (char*)(clean.c_str()); 
return toReturn; 
} 
+0

Qu'est-ce que 'cleanse'? Une fonction? Postez son code. Renvoie-t-il le tableau char local? – Nawaz

+0

Si ça fait mal quand vous faites quelque chose, ne le faites pas. Arrêtez d'utiliser char *, Word * et utilisez les chaînes std :: et un vecteur de Word. Et repensez le nom de votre structure - pourquoi est-ce appelé Word? –

Répondre

2

Le problème est sans doute que Dans cleanse, vous renvoyez clean.c_str().

Cette valeur de pointeur cesse d'être valide lorsque clean cesse d'exister, ce qui correspond à la fin de la fonction. Il n'est plus garanti de pointer vers quoi que ce soit, c'est donc de la chance que vous voyez la chaîne "de nouveau" comme prévu.

Ce que je pense arrive est que la mémoire utilisée à être occupé par les données pour la chaîne clean dans cleanse, a été réutilisée pour la structure word, mais il est pas immédiatement écrasé.Il se trouve que l'octet qui contenait le premier a contient maintenant une partie du membre same de votre structure. Ainsi, lorsque vous écrivez un pointeur nul à node->same, cela a pour effet d'écrire un 0 octet à l'emplacement pointé par node->clean. Par la suite, il semble pointer vers une chaîne vide.

0

D'accord, nous aurions besoin de voir réellement le code pour certains d'entre eux pour être sûr, mais voici ce que le bug vous dit: à un moment donné, vous affectez à quelque chose qui supprime votre ou écrase nettoyer. Puisque y, vous le déclarez comme un char *, je suppose que vous l'utilisez comme un pointeur vers un tableau de caractères, et les chances sont bonnes qu'un tableau soit aliasé à deux pointeurs "propres" dans deux mots différents.

2

Vous devez réduire votre code à un exemple minimal qui affiche le problème et l'afficher.

Le code suivant ne parvient pas à afficher le problème. Le contenu de main et la définition de Word sont copiés à partir de votre code, j'ai ajouté le code nécessaire pour le compiler:

#include <iostream> 
#include <cstring> 
using namespace std; 

typedef int SongId; 

struct Word{ 
    char* clean; 
    int size; 
    int position; 
    SongId id; 
    Word* same; 
    Word* diff; 
}; 

char *cleanse(const char *w) { 
    return (char *)w; 
} 
const char *word = "again "; 
const int position = 1739; 
const int id = 0; 

int main() { 
    char* clean = cleanse(word); 
    Word* node = new Word; 
    node->size = strlen(word); 
    node->clean = clean; 
    cout<<"MADE NODE FOR "<<node->clean<<endl; 
    node->position = position; 
    cout<<"4 node clean: "<<node->clean<<endl; 
    node->id = id; 
    cout<<"5 node clean: "<<node->clean<<endl; 
    node->same = NULL; 
    cout<<"6 node clean: "<<node->clean<<endl; 
    cout<<"node position: "<<node->position<<endl; 
    cout<<"node size: "<<node->size<<endl; 
    node->diff = NULL; 
} 

sortie est:

MADE NODE FOR again 
4 node clean: again 
5 node clean: again 
6 node clean: again 
node position: 1739 
node size: 6 
0

En plus de nouvelles et Cout cela pourrait aussi bien être C.

Une autre lecture
What are the differences between struct and class in C++?
char * Vs std::string
Remove spaces from std::string in C++
tolower function for C++ strings
How can I negate a functor in C++ (STL)?

Essayez l'alternative suivante (échantillon non compilé)

#include <iostream> 
#include <string> 
#include <algorithm> 
#include <functional> 

typedef int SongId; 

class Word{ 
    int position; 
    SongId id; 
    Word* same; 
    Word* diff; 

public: 
    const std::string word; 

    const int size() const { return clean.length() }; 

    Word(const std::string& word_, const int position_ = 1739, const int id_ = 0) 
    : clean(cleanse(word_)) 
    , position(position_) 
    , id(id_) 
    , same(NULL) 
    , diff(NULL) 
    { 
    cout<<"MADE NODE FOR "<< word_ << "\n" 
     <<"node clean: "<< word << "\n" 
     <<"node position: "<< position << "\n"; 
     <<"node size: "<< size() << endl; 
    } 

    static std::string cleanse(const std::string& dirty) 
    { 
    string clean(dirty); 

// Remove anything thats not alpha num 
    clean.erase(remove_if(clean.begin(), clean.end(), std::not1(::isalnum)), clean.end()); 
// make it lower case 
    std::transform(clean.begin(), clean.end(), clean.begin(), ::tolower); // or boost::to_lower(str); 

    return clean; 
    } 
}; 

const char *word = "again "; 

int main() { 
    Word* node = new Word(word); 
} 
Questions connexes