J’ai le problème suivant:
void add(){ cRow Row(); Row.add("Column", "Value"); std::vector mRows; mRows.push_back(Row); } cRow::cRow(): mCol(NULL), mVal(NULL) { } cRow::add(const char* Col, const char* Val){ mCol = strdup(Col); mVal = strdup(Val); } cRow::~cRow(){ free(mCol); free(mVal); }
Après avoir ajouté la variable locale Row au vecteur, le destructeur est appelé pour cette ligne et les chaînes sont libérées.
Bien évidemment, les pointeurs vers les chaînes de la ligne stockée dans le vecteur sont également libérés. Tout access aux lignes après avoir quitté l’étendue locale entraînera des erreurs de segmentation.
Le dump des lignes traite après 2 appels comme ça:
| (null) | (null) | ----------------------------------------------------- | (null)| (null) | | LastContainerUpdatePropagation| 1307967498 | ------------------------ END ------------------------
après 3 appels:
| (null) | (null) | ----------------------------------------------------- | (null)| (null) | | (null)| (null) | | LastSystemUpdatePropagation| 1307967498 | ------------------------ END ------------------------
et après avoir quitté la scope complètement sans append de nouvelle ligne, chaque ligne était libérée.
Alors, maintenant ma question: Comment std: vector copie-t-il les objects? Que dois-je faire pour conserver les pointeurs sur les chaînes ou pour les copier dans un autre espace?
Merci beaucoup!
std::vector
utilise le constructeur de copie pour copier des objects. Comme vous n’avez pas défini de constructeur de copie, il utilisera le constructeur de copie implicite C ++ , qui copie simplement tous les membres de manière récursive. cela ne suffit pas, car vous gérez manuellement la mémoire.
Vous devez soit définir votre propre constructeur de copie, soit utiliser quelque chose comme std::ssortingng
, qui fera le bon choix si copié.
Selon les bonnes pratiques, toute classe ayant un destructeur non sortingvial devrait avoir un constructeur de copie et un opérateur d’affectation de copie, précisément pour cette raison (on appelle cela la règle de trois ). Si un constructeur de copie n’a pas de sens (par exemple, pour des choses comme ostream
), il doit être rendu privé, afin d’empêcher toute copie accidentelle.
std::vector
utilise le constructeur de copie pour initialiser ses éléments. Si vous n’avez pas écrit explicitement, le compilateur en fournit un, mais comme vous gérez la mémoire, vous devez soit:
cRow
(notez que vous devrez toujours fournir le constructeur de copie, l’opérateur d’affectation de copie et le destructeur appropriés. votre conteneur RAII). const char*
, qui pourrait être remplacé par std::ssortingng
, qui gérera la gestion de la mémoire. Remarque: seule l’approche n ° 3 évite d’avoir à écrire une version personnalisée des trois fonctions.