2010-08-11 4 views
2

Est-ce que l'instruction "delete" ci-dessous "double gratuitement" un objet?La déclaration "delete" libère-t-elle doublement un objet?

(...object_list is a global vector<object*>...) 

vector< object * >::iterator  it, eit, iter; 
object *p_object; 
vector< object * > dead_objects; 

it = object_list_.begin(); 
eit = object_list_.end(); 

//---collect pointers of all dead objects to dead_objects vector 
for (; it != eit; it++) 
{ 
    p_object = *it; 
    if (p_object->is_dead() == false) 
     continue; 

    dead_objects.push_back(p_object); 
} 

//---free every dead object from the global object_list 
for (iter = dead_objects.begin(); iter != dead_objects.end(); iter++) 
{ 
    p_object = *iter; 

    it = object_list_.begin(); 
    eit = object_list_.end(); 

    for (; it != eit; it++) 
    { 
     if (*it != p_object) 
      continue; 

     object_list_.erase(it); 
     delete p_object; 
     break; 
    } 
} 

Je pose la question parce que la déclaration erase() aurait dû appeler au-dessus du destructor d'un objet et libéré déjà, devrait-il pas?

Répondre

2

erase() n'appelle le destructeur de l'objet, mais le destructor d'un type de pointeur (comme object * ici) ne fait rien - il ne remet pas supprimer le pointeur. Si vous voulez qu'il appelle la suppression, vous devez utiliser un objet (tel que auto_ptr<object *>) qui appelle la suppression.

+0

merci pour la réponse !! J'ai eu la question parce que dans un autre programme j'utilise la carte et le programme a planté quand j'ai déréférencé un objet * après que j'ai appelé erase() pour enlever l'objet * de la carte. (J'utilise VC++ 6) donc je me demande si le vecteur .erase() libère aussi l'objet. – cow

0

Il semblerait que non; Si vous avez un vecteur de pointeurs sur des objets, appeler erase() pour en supprimer un seul supprime simplement le pointeur du vecteur. Vous devez toujours le supprimer vous-même, car les conteneurs STL sont principalement conçus pour collecter des objets par valeur. Juste un couple de suggestions - IMO votre code serait plus clair si vous utilisiez des algorithmes STL comme std::find au lieu de boucler tous vos vecteurs à la main. Je ne suis pas sûr du but de dead_objects vs object_list - vous ne semblez rien gagner en les stockant dans le vecteur temporaire, mais quelque chose a peut-être été perdu en copiant le code dans SO. Et std::vector n'est pas optimale pour beaucoup d'effacements aléatoires comme ceci puisque erase s'exécute en temps linéaire - std::remove suivi de erase serait une approche plus efficace. Par exemple:

for(vector<object*>::iterator it = object_list.begin(); it != object_list.end(); ++it) { 
    if((*it)->is_dead()) { 
     delete *it; 
     *it = NULL; 
    } 
} 
object_list.erase(std::remove(object_list.begin(), object_list.end(), NULL), object_list.end()); 
+0

merci pour la réponse! mais n'est pas votre dernière déclaration object_list.erase (std :: remove (object_list.begin(), object_list.end(), NULL), object_list.end()); effacer TOUS les objets, morts et vivants? – cow

+0

Non - 'remove' supprime tous les éléments de la liste égaux à NULL et renvoie un itérateur juste après le dernier élément valide. L'appel 'erase' tronque alors le vecteur à cette nouvelle longueur. – Peter

+0

je l'ai eu. merci pour le super tour de troncature !! – cow