2010-10-18 6 views
2

Je lis des chaînes en C++ en utilisant fread où je lis et stocke shortSiteText dans siteNames_. siteNames_ est déclaré comme std::vector<char*> siteNames_; J'utilise siteNames_ dans d'autres fonctions mais parce que shortSiteText est un pointeur, lorsque j'appelle la commande delete, la dernière entrée dans siteNames_ est modifiée. Comment puis-je empêcher cela?Empêche le dernier élément dans char * vector de changer

for (unsigned int i = 0; i <= nSites; i ++){ 
    fread((char *) &shortSiteTextLength, 1, sizeof shortSiteTextLength, baseFile_); 
    shortSiteText = new char[shortSiteTextLength]; 
    fread(shortSiteText,1, shortSiteTextLength,baseFile_); 
    siteNames_.push_back(shortSiteText); 
} 
delete [] shortSiteText; 

J'ai essayé d'utiliser l'opérateur de déréférencement: siteNames_.push_back(*shortSiteText); mais qui génère une erreur de compilation.

REMARQUE: Je dois utiliser fread et char * en raison du code existant.

+2

Pourquoi ne pas utiliser 'std :: string'? Chaque fois que vous avez 'delete 'dans votre code, quelque chose pourrait très probablement être amélioré. – GManNickG

+0

@GMan, j'utilise un code hérité ailleurs – Elpezmuerto

+4

C'est ce à quoi sert 'c_str' /' data'/'& s [0]'. Et si cela ne fonctionne pas pour vous, faites 'std :: vector ' et '& v [0]' à la place. ** Vous ne devriez jamais avoir à supprimer manuellement quelque chose. ** Votre problème entier est dû à une propriété imprécise, parce que vous essayez de le prendre en main. C'est dangereux et bug-monté. – GManNickG

Répondre

2

Let s zoom sur ce point:

shortSiteText = new char[shortSiteTextLength]; 
siteNames_.push_back(shortSiteText); 
delete [] shortSiteText; 

Explication: La deuxième ligne pousse juste un pointeur vers le tableau, pas le tableau lui-même. La première ligne désalloue ensuite le tableau sur lequel pointe toujours le dernier élément de siteNames; cela conduit à un comportement indéfini lorsque vous utilisez cet élément.

Hack: Supprimer delete [] shortSiteText

réel fix: Vous rencontrez ce problème parce que vous essayez de gérer vous-même objet ownerships. Ne pas!Ici, vous pouvez utiliser std::string et toujours être en mesure de travailler avec du code hérité, avec la fonction membre c_str().

Pour citer un de mes amis:

En règle générale, si vous êtes un débutant et votre code indique, vous avez « char » mot un bug.

+0

Je suis d'accord avec cette citation, j'ai été plus ou moins obligé d'utiliser char et je n'étais pas content de ça. J'espérais éviter de pirater la solution sans révision sérieuse du code, semble que je ne peux pas le faire – Elpezmuerto

+0

@Elpezmuerto: Avez-vous même lu mon commentaire? Vous n'avez pas besoin d'allocation manuelle de char. – GManNickG

3

Vous ne pouvez pas delete[] tout ce que vous poussez dans le vector jusqu'à ce que l'élément vector associé soit terminé. Ce n'est pas clair pour moi ce que l'intention de ce code est - vous ne supprimez la dernière valeur utilisée de shortSitetext de toute façon, donc cela ne fait pas ce que vous pensez (qui essaie d'éviter la fuite de mémoire en faisant correspondre new avec delete, je pense).

Retirez la dernière ligne de code, et nettoyer manuellement le vector lorsque vous avez terminé avec elle par itérer sur les éléments appelant delete[] pour chacun, puis clear() la vector.

Ou utilisez boost::ptr_vector, qui le fera automatiquement pour vous.

Ou utilisez vector<string>, pour découpler le code hérité char* à partir de votre pointeur moderne non brut en utilisant le monde C++. Vous pouvez push_back const char* directement à un vector<string> comme ceci:

const char* str; 
// init str to the value you wish 

vector<string> vec; 
vec.push_back(str); 
0

Ne pas supprimer shortSiteText jusqu'à ce que vous voulez supprimer les données du vecteur.

Vous avez créé un morceau de mémoire, défini les données et enregistré le pointeur dans votre vecteur. La mémoire que vous supprimez est la même que celle à laquelle pointe l'élément vectoriel.

Vous venez de supprimer la ligne delete [] shortSiteText;. Mais, assurez-vous que lorsque vous avez terminé avec le vecteur, supprimez et supprimez chaque pointeur avec précaution.

Questions connexes