Problem mit delete[ ], please help!



  • Tag alle zusammen und noch nen Gesundes Neues!

    Also folgendes, ich habe hier eine Klasse die als Eigenschaft einen Pointer vom typ einer selbst definierten Struktur hat. In einer Methode der Klasse allociere ich mit dem Zeiger ein beliebig großes array:

    // delete[ ] this->m_Part;
        // this->m_Part = 0;
        this->m_Part = new PuzzelPart[ this->m_iLevel ];
    

    So nun kann ich mit dem Zeiger und dem allocierten Speicher arbeiten. Beschliesst jetzt aber der Benutzer das Level zu erhohen oder zu senken, brauche ich je nach dem mehr/weniger Speicher, also will ich dann erst einmal den alten Speicher auf den der Zeiger zeigt frei geben, versuche ich das aber so:

    delete[ ] this->m_Part;
         this->m_Part = 0;
    

    Windows has triggered a breakpoint in Desktop_Drawing.exe.
    
    This may be due to a corruption of the heap, which indicates a bug in Desktop_Drawing.exe or any of the DLLs it has loaded.
    
    This may also be due to the user pressing F12 while Desktop_Drawing.exe has focus.
    
    The output window may have more diagnostic information.
    [quote]
    
    weiter:
    

    ---------------------------
    Microsoft Visual C++ Debug Library
    ---------------------------
    Debug Assertion Failed!

    Program: ...tudio 2008\Projects\Desktop_Drawing\Debug\Desktop_Drawing.exe
    File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c
    Line: 1317

    Expression: _CrtIsValidHeapPointer(pUserData)

    For information on how your program can cause an assertion
    failure, see the Visual C++ documentation on asserts.

    (Press Retry to debug the application)
    ---------------------------
    Abbrechen Wiederholen Ignorieren
    ---------------------------
    [code]

    Hat einer ne Idee wie ich das in den griff bekomme?

    Danke schon mal.

    Gruß Tobi.



  • Scheinst vorher schon außerhalb des gültigen Bereichs deines Arrays zu kommen...



  • Du hast dir irgendwie den Speicher kaputt geschrieben. Steht ja auch in der Meldung. Z.B. in dem du außerhalb des reservierten Speicherbereiches geschrieben hast.

    Warum benutzt du eigentlich nicht einfach vector und die at()-Methode? Dann passiert sowas nicht...



  • Alles wegen der Übung, deswegen wollt ich einfach mal new[] und delte[] verwenden.

    Hier sind die einzigen Funktionen mit dem ich mit dem Pointer arbeite:

    void CPuzzel::m_UpdatePuzzelParts( int xPos, int yPos ) {
    
        int iCounter = 0;
    
        for( int i = 0; i < this->m_iLevel; i++ ) {
    
            for( int j = 0; j < this->m_iLevel; j++ ) {
    
                this->m_Part[ iCounter ].iID.x = j;
                this->m_Part[ iCounter ].iID.y = i;
    
                // ***** Clear old rgn *****
                this->m_Part[ iCounter ].hPartRgn = 0;
    
                this->m_Part[ iCounter ].hPartRgn = ::CreateRectRgn( xPos + ( j * ( this->m_Bmp.bmWidth / this->m_iLevel + 3 ) ), 
                                                                     yPos + ( i * ( this->m_Bmp.bmHeight / this->m_iLevel + 3 ) ),
                                                                     ( xPos + ( j * ( this->m_Bmp.bmWidth / this->m_iLevel + 3 ) ) + ( this->m_Bmp.bmWidth / this->m_iLevel ) ),
                                                                     ( yPos + ( i * ( this->m_Bmp.bmHeight / this->m_iLevel + 3 ) ) + ( this->m_Bmp.bmHeight / this->m_iLevel ) ));
    
                iCounter++;
            }
        }
    }
    
    void CPuzzel::m_MergePuzzelParts( ) {
    
        int iCounter = 0;
        bool bOK;
    
        // ***** Clear old Ids *****
        for( int i = 0; i < ( this->m_iLevel * this->m_iLevel ); i++ ) {
    
            this->m_Part[ i ].iID.x = -1; 
            this->m_Part[ i ].iID.y = -1;
        }
    
        do {
    
            bOK = true;
    
            this->m_Part[ iCounter ].iID.x = rand( ) % this->m_iLevel; 
            this->m_Part[ iCounter ].iID.y = rand( ) % this->m_iLevel; 
    
            for( int i = 0; i < ( this->m_iLevel * this->m_iLevel ); i++ ) {
    
                if( i == iCounter )
                    continue;
    
                if( ( this->m_Part[ iCounter ].iID.x == this->m_Part[ i ].iID.x ) && 
                    ( this->m_Part[ iCounter ].iID.y == this->m_Part[ i ].iID.y ) ) {
    
                        bOK = false;
                        break;
                }
            }
    
            if( bOK )
                iCounter++;
    
        } while( iCounter < ( this->m_iLevel * this->m_iLevel ) );
    
        // ***** Isnt merged *****
        if( m_bPuzzelComplete( ) ) {
    
            m_MergePuzzelParts( );
        }
    }
    
    void CPuzzel::m_SwapPuzzel( int first, int second ) {
    
        PuzzelPart temp = this->m_Part[ first ];
    
        this->m_Part[ first ].iID = this->m_Part[ second ].iID;
        this->m_Part[ second ].iID = temp.iID;
    }
    

    Wo mach ich da jetzt nen fehler?

    Gruß Tobi.



  • Na der Fehler ist leicht:

    for( int i = 0; i < this->m_iLevel; i++ ) {
    
            for( int j = 0; j < this->m_iLevel; j++ ) {
    

    Das ergibt m_iLevel * m_iLevel durchgänge(iCounter++). Du hast aber nur einen Bereich von m_iLevel reserviert 😉

    this->m_Part = new PuzzelPart[ this->m_iLevel * this->m_iLevel];
    

    und es geht 😉



  • Wenn ich das richtig sehe allokierst Du m_iLevel mal Speicherplatz, greifst dann aber auf m_iLevel^2 Elemente zu.



  • oh verdammt stimmt, jetzt seh ich es auch 😃 d.h. es muss so heissen:

    this->m_Part = new PuzzelPart[ this->m_iLevel * this->m_iLevel ];
    

    Okay danke euch.

    Gru0 Tobi.


Anmelden zum Antworten