Debug assertion failed... warum?



  • hallo liebe coder,

    hier mein code.
    die idee = eleminieren eines wertes bei knopfdruck. in dem array dann natürlich auch.

    realisierung:

    nt  CGraph::DelPoint ( int ipos )
    {
    	if ( ipos > -1 )
    	{
    		// Überschreibe gewählte Position mit der jeweils Nächsten
    		for ( ipos ; ipos < m_nXY-1 ; ipos++ )
    		{
    			m_xy[ipos].x = m_xy[ipos+1].x;
    			m_xy[ipos].y = m_xy[ipos+1].y;
    		};
    
    		// Aktualisiere die Anzahl der Plaetze im Speicher m_nXY 
                        (also einer weniger)
    		m_nXY--;
    
    		// Speicher mit einem Platz weniger buchen
    		XY * xy = new XY [m_nXY -1];
    
    		if(m_xy)
    		{	// Kopiere den Inhalt ohne die letzte Leere Stelle
    			memcpy ( xy, m_xy, m_nXY * sizeof(XY) );
    
    			delete [] m_xy;
    		}
    
    		// Loeschen des alten Speichers
    		m_xy = xy;
    
    		// Setzte die letzte Position als die Groesste
    		m_xMax = m_xy[m_nXY -1].x;
    		m_yMax = m_xy[m_nXY -1].y;
    	}
    	else
    	{
    		return -1;
    	};
    	return ipos;
    }
    

    das macht er erst wenn ich das zweite mal etwas lösche,
    also wenn schonmal die methode durchlaufen ist.

    ich lösche aber doch immer den alten speicher und das new XY ist doch auch
    nur solange gältig, wie die Methode selbst existiert... ?!??

    danke für die schnelle hilfe



  • Was ist XY?
    Besitzt XY virtuelle Funktionen?



  • nein...

    XY ist eine Struktur...

    typedef struct tagXY {
    	double x;
    	double y;
    } XY;
    

    belege ich neuen speicher...
    hast du ne ahnung warum das nicht funzt?



  • delete [] m_xy;
    m_xy = 0;
    

    Sonst geht der Vergleich if (m_xy) { ... } nicht.



  • das ist ein netter hinweis, danke...

    jedoch leider nicht die lösung...
    der meckert weiterhin über das

    delete [] m_xy;
    

    beim zweiten male löschen!

    verstehe das echt nicht....


  • Mod

    int  CGraph::DelPoint ( int ipos )
    {
    	if ( ipos > -1 )
    	{
    		// Überschreibe gewählte Position mit der jeweils Nächsten
    		for ( ipos ; ipos < m_nXY-1 ; ipos++ )
    		{
    			m_xy[ipos].x = m_xy[ipos+1].x;
    			m_xy[ipos].y = m_xy[ipos+1].y;
    // du kannst auch die Strukturen direkt Zuweisen:
    //                      m_xy[ipos] = m_xy[ipos+1];
    // noch besser ist std::copy
    		};
    
    		// Aktualisiere die Anzahl der Plaetze im Speicher m_nXY 
                        (also einer weniger)
    		m_nXY--;
    
    		// Speicher mit einem Platz weniger buchen
    		XY * xy = new XY [m_nXY -1];  // !!! wieso -1 ? damit resevierst du ein Element zuwenig (was dann beim memcpy zu undefiniertem Verhalten wird)
    
    		if(m_xy)
    // überflüssig, falls m_xy vorher NULL war, hattest du keine Elemente und konntest daher gar nichts löschen
    // ein assert wäre angebracht
    		{	// Kopiere den Inhalt ohne die letzte Leere Stelle
    			             memcpy ( xy, m_xy, m_nXY * sizeof(XY) );
    // keine Einwände, aber std::copy ist angebracht
    // zudem kombiniert man das am Besten mit der vorherigen Kopie
    
    			delete [] m_xy;
    		}
    
    		// Loeschen des alten Speichers
    		m_xy = xy; // Eigentlich hat das Löschen schon beim delete[] stattgefunden, hier aktualisierst du nur die entsprechende Membervariable
    
    		// Setzte die letzte Position als die Groesste
    		m_xMax = m_xy[m_nXY -1].x;
    		m_yMax = m_xy[m_nXY -1].y;
                    // !!!! was wenn m_nXY 0 ist ?
    	}
    	else
    	{
    		return -1;
    	};
    	return ipos;
    }
    
    typedef struct tagXY {
        double x;
        double y;
    } XY;
    

    Das ist C-Style. In C++ gibt es keine Tag-Namen, und auch in C ist es nicht unbedingt üblich, einen anderen Bezeichner dafür zu verwenden. Besser also

    struct XY { double x,y; };
    

    mithin

    int  CGraph::DelPoint ( int ipos )
    {
        if ( ipos < 0 )
            return -1;
    
        assert( ipos < m_nXY );
    
        XY* new_xy = new XY[ --m_nXY ];
        std::copy( m_xy, m_xy + ipos, new_xy ); // alle Positionen vor ipos
        std::copy( m_xy + ipos + 1, m_xy + m_nXY + 1, new_xy + ipos );
        delete [] m_xy;
        m_xy = new_xy;
    
        // Setzte die letzte Position als die Groesste, bzw. 0 wenn das Array leer ist
        m_xMax = m_nXY ? m_xy[m_nXY -1].x : 0;
        m_yMax = m_nXY ? m_xy[m_nXY -1].y : 0;
    
        return ipos;
    }
    

    eigentlich sollte das sowieso einen vector benutzen, mit std::vector<XY> m_xy :

    int  CGraph::DelPoint ( int ipos )
    {
        if ( ipos < 0 )
            return -1;
    
        assert( ipos < m_xy.size() );
    
        m_xy.erase( m_xy.begin() + ipos );
        // ggf. std::vector<XY>(m_xy).swap(m_xy);
    
        m_xMax = m_nXY ? m_xy.back().x : 0;
        m_yMax = m_nXY ? m_xy.back().y : 0;
    
        return ipos;
    }
    

    kurz und schmerzlos.



  • funktioniert super....
    vielen dank... 😉


Anmelden zum Antworten