2017-07-06 4 views
0

J'ai un code qui est destiné à gérer la mémoire, mais il continue de se bloquer à un certain point où je retire un objet de la liste 'live' et le place sur le 'mort' un:L'utilisation consécutive de std :: list provoque un plantage

class MemoryObject { 
private: 
    static std::list <MemoryObject *> alive, dead; 
    long references; 
public: 
    MemoryObject() { 
     alive.push_back(this); 
     references = 0; 
    } 

    static void deepClean() { 
     clean(); 
     std::list<MemoryObject *>::iterator iterator; 
     for(iterator = alive.begin(); iterator != alive.end(); iterator ++) { 
      MemoryObject *object = *iterator; 
      Log::instance().write(DEBUG_LOG, "\nObject still active at the end of the program, check for memory leaks." 
        "\nSize: %d", 
        alive.size()); 
      delete object; 
     } 
     alive.clear(); 
    } 

    void reference() { 
     references ++; 
    } 

    void release() { 
     references --; 
     if(references <= 0) { 
      dead.push_back(this); 
      alive.remove(this); 
     } 
    } 

    static void clean() { 
     std::list<MemoryObject *>::iterator iterator; 
     for(iterator = dead.begin(); iterator != dead.end(); iterator ++) 
      delete(&iterator); 
     dead.clear(); 
    } 

    ~MemoryObject() { 
     clean(); 
    } 
}; 

std::list <MemoryObject *> MemoryObject::alive, MemoryObject::dead; 

Eclipse debug montre qu'il ne en liberté(), toujours à la deuxième place liées aux listes - J'ai essayé de les mettre (alive.remove(this) and dead.push_back(this)) dans un ordre différent, qui ne change rien. Il est intéressant cependant, si je place quelque chose entre eux, comme un printf(), mais il ne tombe pas en panne ...

Voilà où je l'appeler de:

#include <stdlib.h> 
#include <stdio.h> 

#include "log/log.hpp" 
#include "memory/object.hpp" 

int main(int argc, char *argv[]) { 
    MemoryObject foo; 
    foo.release(); 
    MemoryObject::deepClean(); 
    return 0; 
} 
+5

Dans votre fonction '' non polluants vous supprimez (et iterator) '. C'est à peine correct. –

+1

Veuillez montrer comment vous appelez les fonctions. –

+1

S'il vous plaît lire ceci: [mcve] –

Répondre

0

Vous delete seulement ce qui est alloué par new.

MemoryObject foo; 
foo.release(); 

Et à l'intérieur propre

for(iterator = dead.begin(); iterator != dead.end(); iterator ++) 
     delete(*iterator); //I am assuming you have * instead of &(which is incorrect as mentioned in another answer). 

Vous appelez delete() sur quelque chose qui n'a pas été affecté par new Essayez ceci.

MemoryObject *foo=new MemoryObject(); 
foo->release(); 

EDIT: Cela ne fonctionnera toujours pas pour la raison ci-dessous.

intérieur clean() vous supprimons élément de dead qui est this du object.So actuel bref que vous faites quelque chose comme ça

class A 
{ 
    void delete_this() 
    { 
     delete(this); 
     //At this point "this" is a dangling pointer and you should not use it. 
    } 
}; 
1

Dans votre clean fonction que vous avez:

delete(&iterator); 

Ce compilera, mais tentera de supprimer le iterator lui-même - ce qui est sur la pile (qui va se planter).

Je soupçonne que vous vouliez:

delete(*iterator); 
1

Vous ne pouvez pas supprimer un objet qui n'a pas été attribué à nouveau. MemoryObject foo; n'est pas allocatetd avec new.