Fehler: Free Heap block modified after it was freed



  • Hi,
    und zwar erhalte ich die im Titel stehende Fehlermeldung. Hier noch mal komplett:

    HEAP[*.exe]: HEAP: Free Heap block cc5690 modified at cc5b60 after it was freed
    Windows hat einen Haltepunkt in *.exe ausgelöst.

    Dies kann auf eine Beschädigung des Heaps zurückzuführen sein, die auf ein Problem in *.exe oder in einer der geladenen DLLs hinweist.

    Dies kann auch darauf zurückzuführen sein, dass der Benutzer F12 drückt, während *.exe den Fokus hat.

    Klingt eigentlich eindeutig - in eine dynamische Variable wurde nach dem sie freigegeben wurde geschrieben. Doch in meinem Programm gibt es keine solche Variable.
    Ich habe ein Programm geschrieben mit dem man Bilder laden, bewegen, Eigenschaften ändern und so kann. Zur Darstellung verwende ich DirectX. Nach dem ein paar Bilder geladen wurden (meistens 3) erhalte ich die genannte Fehlermeldung. Im Programm gibt es 2 dynmaische Arrays:
    - einer gehört zu einer Klasse und speichert die Bildobjekte
    - der 2. ist ein lokaler (in einer Funtkion)

    Der in der Fehlermeldung genannte Haltepunkt befindet sich immer bei DispatchMessage. Zum löschen der dynamischen Arrays nutze ich folgendes Makro:

    #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p) = NULL; } }
    

    Beide Arrays wurden mit NULL initalisiert. Der lokale Array wird am ende der betreffenden Funktion gelöscht, bei Programmende.

    Folgende Funktion initialisiert ein neues Bild:

    {
    	FILE *file;
    	char error[300];
    	if(( file = fopen( filename, "r" )) == NULL )
    	{
    		sprintf( error, "Die Datei %s konnte nicht gefunden werden!", filename );
    		MessageBox( hWnd, error, "Ladefehler", MB_ICONERROR | MB_OK );
    		return 0; 
    	}
    	fclose( file );
    
    	SPRITE *cpySprite = NULL; 
    	if( AnzSprites > 0 ) 
    	{
    		cpySprite = new SPRITE[AnzSprites];
    		for( int i=0; i<AnzSprites; i++ )
    			cpySprite[i] = Sprite[i];
    	}
    
    	SAFE_DELETE_ARRAY( Sprite );
    	AnzSprites++;
    	Sprite = new SPRITE[AnzSprites];
    
    	Sprite[AnzSprites-1].x		= x;
    	Sprite[AnzSprites-1].y		= y;
    	Sprite[AnzSprites-1].z		= z;
    	Sprite[AnzSprites-1].alpha	= alpha;
    	Sprite[AnzSprites-1].Light  = D3DCOLOR_XRGB( 255, 255, 255 );
    	Sprite[AnzSprites-1].ColorKey = ColorKey;
    	Sprite[AnzSprites-1].UseAlpha = false;
    	Sprite[AnzSprites-1].UseColorKey = false;
    	strcpy( Sprite[AnzSprites-1].filename, filename );
    
    	if( AnzSprites > 0 )
    	{
    		for( int i=0; i<AnzSprites-1; i++ )
    			Sprite[i] = cpySprite[i];
    	}
    
    	D3DXIMAGE_INFO Info;
    	D3DXGetImageInfoFromFile( filename, &Info );
    	if( xSize == D3DX_DEFAULT )
    		xSize = Info.Width;
    	if( ySize == D3DX_DEFAULT )
    		ySize = Info.Height;
    
    	D3DXCreateTextureFromFileEx( d3ddev, filename, xSize, ySize, D3DX_DEFAULT, NULL, D3DFMT_A8R8G8B8, 
    								D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, NULL, NULL, NULL,
    								&Sprite[AnzSprites-1].texture );
    	Sprite[AnzSprites-1].layer = AnzSprites-1;
    	Sprite[AnzSprites-1].type  = Type_Sprite;
    
    	Sprite[AnzSprites-1].width = xSize;
    	Sprite[AnzSprites-1].height = ySize;
    
    	SAFE_DELETE_ARRAY( cpySprite );
    	return &Sprite[AnzSprites-1];
    }
    

    Ich bin hundertmal den Code durchgegangen und auch Google brachte keine Ergebniss die mir halfen.
    Ich hoffe mir kann jemand weiterhelfen.

    MfG.: Flori



  • Versuch mal mit findheapbug.h

    void * __cdecl operator new(unsigned int x)
    {
    	return VirtualAlloc(0, x, MEM_COMMIT, PAGE_READWRITE);
    }
    void __cdecl operator delete(void *p)
    {
    	VirtualFree(p, 0, MEM_RELEASE);
    }
    

    Statt 'Free Heap block modified' kriegst Du access violation.
    Es muß ein array-out-of-index-write sein.



  • Einfacher ist es mittels glflags.exe den Page-Heap zu aktivieren. Dann geht es für *alle* allokationen (nicht nur new/delete) und er macht genau das gleiche.


  • Mod



  • ok, den Code von sapero hab ich schon mal ausprobiert, das Resultat ist folgendes:
    - der Fehler kommt nicht aber die Bilder kommen durcheinander

    Ist wohl ein Fehler in den Objektarrays, wie du bereits sagtest:

    Es muß ein array-out-of-index-write sein.

    glflags nimmt bei launch nur Commandozeilenprogramme an oder? spuckt zumindest nen Fehler aus. Oder kann man das auch anders starten?

    kann es sein das der Application Verifier in der Express nicht enthalten ist? zumindest gibt es die in der Microsoft-Anleitung beschriebene Option bei mir im Menü nicht

    ich geh noch mal die Array Indexes durch vielleicht versteckt sich dort der Fehler


  • Mod

    GFLAGS funktioniert mit jeder Art von Programm.

    Den Application Verifier kann man auch separat starten.


Log in to reply