problem bei delete



  • ich habe in etwa folgenden code:

    classA::classA()
    {	
    	m_pointerA = NULL;
    	m_pointerB = NULL;
    
    	m_pointerA = new classB();
    }
    
    classA::~classA()
    {
    	if(m_pointerA)
    	{
    		delete m_pointerA;
    	}
    
    	if(m_pointerB)
    	{
    		delete m_pointerB; // PROBLEM
    	}
    
    }
    

    meiner meinung nach sollte das programm ja nicht an die // PROBLEM
    stelle kommen.

    was kann da schieflaufen?



  • erstens: Wie äußert sich das Problem? (Fehlermeldung, evt. etwas Quellcode)

    zweitens: Die defaultmäßig bereitgestellten Copy-Ctoren und Zuweisungsoperatoren kommen mit dynamisch reserviertem Speicher nicht klar - da solltest du dir selber welche anfertigen.



  • o.k.
    naja zuerst einmal geht er in den body der
    if-abfrage obwohl ja im konstruktor der pointer auf NULL gesetzt wurde.
    der pointer wird dann auch bis zum destruktor nicht mehr angerührt.

    beim delete bekomme ich dann eine unhandled exeption at 0xirgendwas.
    funktion

    void operator delete(
            void *pUserData
            )
    {
    ...
      /* verify block type */
        _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); //HIER
    
        ...
    }
    

    Access violation reading location 0xcdcdcdc1.



  • Setz' mal einen Breakpoint auf den Anfang des Destruktor's und schau dir an, was in den Member-Variablen drinsteht.

    (btw, interessanter (und nützlicher für die Diagnose) wäre übrigens der Code gewesen, in dem du deine Klasse nutzt)



  • o.k.

    classA::~classA()
    {
    	 :arrow_right: if(m_pointerA)
    	{
    		delete m_pointerA;
    	}
    
    	if(m_pointerB)
    	{
    		delete m_pointerB; // PROBLEM
    	}
    
    }
    

    breakpoint beim pfeil.
    m_pointerA=0x008c09f0
    m_pointerB=cdcdcdcdcd

    code dazwischen ist recht viel.
    pointerB wird jedoch ausser im konstruktor und im destruktor nicht verwendet!



  • asr schrieb:

    m_pointerB=cdcdcdcdcd

    Das ist der Wert, den MSVC in der Debug-Version uninitialisierten Variablen gibt. Erstellst du überhaupt ein Objekt dieser Klasse?



  • asr schrieb:

    pointerB wird jedoch ausser im konstruktor und im destruktor nicht verwendet!

    Sicher? Wozu verwendest du ihn dann?

    btw, versuch mal dein Programm auf, das nötigste zu beschränken - tritt der Fehler immer noch auf, wenn du nur ein classA-Objekt anlegst und wieder freigibst?



  • ich habe nun eine überfrüfung gleich in den konstruktor gemacht.

    und das programm will wieder beide deletes ausführen.
    if(pointer != NULL)
    oder
    if(pointer != 0)
    ändert auch nichts daran

    classA::classA()
    {	
    	m_pointerA = NULL;
    	m_pointerB = NULL;
    
    	m_pointerA = new classB();
    
    	if(m_pointerA)
    	{
    		delete m_pointerA;
    	}
    
    	if(m_pointerB)
    	{
    		delete m_pointerB; 
    	}
    }
    

    noch eine andere idee?



  • Verwende mal eine Initialisierungsliste:

    classA::classA() : m_pointerA(new classB()), m_pointerB(NULL)
    {
      cout<<"A:"<<(void*)m_pointerA<<"\nB:"<<(void*)m_pointerB<<endl;
    }
    

    (btw, wie sind eigentlich die Member-Variablen genau definiert?)



  • mit initlialisierungsliste klappt es!

    thx



  • vielleicht geht der optimizer der ms-compilers ja noch davon aus, daß der pointer automatisch auf 0 initialisiert wird und entfernt deshalb bm_pointerB = NULL. warscheinlich ein compilerfehler.



  • asr schrieb:

    und das programm will wieder beide deletes ausführen.

    Dann machst du aber etwas im ctor, was du uns verschweigst. Ein Compilerfehler ist es mit Sicherheit nicht. Zumindest kann ich das von der aktuellen Version behaupten. Die if Abfragen sind übrigens unnötig, das macht delete schon selber. Und m_pointerA mit einem Nullzeiger zu initialisieren, macht in deinem Beispiel auch keinen Sinn.



  • groovemaster schrieb:

    asr schrieb:

    und das programm will wieder beide deletes ausführen.

    Dann machst du aber etwas im ctor, was du uns verschweigst. Ein Compilerfehler ist es mit Sicherheit nicht. Zumindest kann ich das von der aktuellen Version behaupten. Die if Abfragen sind übrigens unnötig, das macht delete schon selber. Und m_pointerA mit einem Nullzeiger zu initialisieren, macht in deinem Beispiel auch keinen Sinn.

    will ja gar nicht abstreiten dass das etwas komisch klingt 🙂

    allerdings habe ich den ganzen abschnitt umgeschrieben, dieses mal eine initilisierungsliste verwendet und dann ging es.
    der code war auch nur schematisch, in wirklichkeit passieren an dieser stelle noch viele andere sachen.


Anmelden zum Antworten