Comment std :: vector copie les objects dans sa mémoire interne

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:

  1. Fournir un constructeur de copie, un opérateur d’affectation de copie et un destructeur (voir la règle de trois )
  2. Utilisez RAII et créez un petit wrapper qui gère l’ensemble de la gestion de la mémoire pour une valeur unique, et utilisez-en autant que nécessaire dans votre classe 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).
  3. Utilisez un type qui gère la mémoire pour vous. Dans votre exemple, vous utilisez 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.