Problem mit Methode



  • Hallo, da ich mich im Moment mit DirectX befasse, bin ich dabei mir eine Sprite-Klasse zu erstellen. Um ein Sprite zu laden, benutze ich folgende Methode:

    CSprite.cpp

    //...
    VOID CSprite::Load( LPSTR lpszName, LPSTR lpszFile )
    {
    	if( m_mapTextures.find( lpszName ) != m_mapTextures.end() )
    	{
    		return;
    	}
    	else{
    		LPDIRECT3DTEXTURE9 lpTexture;
    
    		if( FAILED( D3DXCreateTextureFromFileEx( m_lpDevice,
    												 lpszFile,
    												 D3DX_DEFAULT_NONPOW2,
    												 D3DX_DEFAULT_NONPOW2,
    												 1,
    												 NULL,
    												 D3DFMT_UNKNOWN,
    												 D3DPOOL_MANAGED,
    												 D3DX_DEFAULT,
    												 D3DX_DEFAULT,
    												 NULL,
    												 NULL,
    												 NULL,
    												 &lpTexture ) ) )
    		{
    			FILE *pFile;
    
    			pFile = fopen( "C:\\error.txt", "w" );
    			fprintf( pFile, "CSprite::Load() fehlgeschlagen." );
    			fclose( pFile );
    		}
    		else{
    			m_mapTextures[lpszName] = lpTexture;
    		}
    	}
    }
    //...
    

    Wenn ich die Methode nun in CMain.cpp aufrufe, funktioniert alles fehlerfrei. Die Sprites werden geladen und auch angezeigt.

    CMain.cpp:

    //...
    m_pSprite = new CSprite();
    //...
    m_pSprite->Load( "map", "c:\\test.png" );
    

    Wenn ich aber dieselbe Methode in einer anderen Datei aufrufe, klappt es auf einmal nicht mehr.

    CMenu.cpp

    //...
    m_pSprite = new CSprite();
    //...
    m_pSprite->Load( "map", "c:\\test.png" );
    

    Ich kriege dann immer folgende Fehlermeldung:

    Eine Ausnahme (erste Chance) bei 0x00621421 in 2DSpiel.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcdcdcdcd.
    Unbehandelte Ausnahme bei 0x00621421 in 2DSpiel.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcdcdcdcd.
    Das Programm "[3212] 2DSpiel.exe: Systemeigen" wurde mit Code 0 (0x0) beendet.

    Der Fehler soll wohl irgendwo in D3DXCreateTextureFromFileEx() liegen.



  • also:
    FILE *pFile; ist C... C++ hat streams...

    m_pSprite = new CSprite(); lass mal die Klammern weg und sag, obs dasnn klappt ^^

    bb



  • Wenn ich die Klammern weg lasse, bekomme ich immer noch die gleiche Fehlermeldung.


  • Administrator

    @unskilled,
    Die klammern muss man nur bei sowas weglassen:
    CSprite Sprite;
    Wenn man die Klammern belassen würde, würde dies als Funktionsdeklaration angesehen werden.

    @Barney Gumble,
    Die Adresse 0xcdcdcdcd ist ein Hinweis auf eine ungültige Adresse, wie es auch schon die Zugriffsverletzung ist. Diese spezielle Adresse wird bei der MFC und bei DirectX im Debug-Modus gesetzt, wenn ein delete aufgerufen wurde. Zumindest habe ich das so in Erinnerung.

    Naja, wie auch immer, allgemein kann man sagen, dass du irgendwo eine ungültige Adresse übergibst. Entweder noch nicht initialisiert oder bereits gelöscht. Dies führt dann zur Zugriffsverletzung. Überprüf also mal, allenfalls mit dem Debugger, dass du gültigen Speicher übergibst.

    Grüssli



  • Geh da halt mal mit dem Debugger durch, dann siehst du, wo der Fehler liegt.

    btw:
    Dieses "Logging-System" ist aber nicht dein ernst, oder? - Du schreibst in eine Datei rein, die du jedesmal öffnest? Und dann nichtmal append?



  • Das Problem liegt bei m_lpDevice. Wenn ich die Variable beim Funktionsaufruf als Parameter übergebe funktioniert alles einwandfrei. Wenn ich aber die Variable in einer anderen Funktion erst als Parameter übergebe, dann als Member-Variable abspeichere und dann mit einer anderen Funktion auf die abgespeicherte Variable zugreife, funktioniert es auf einmal nicht mehr. Woran kann das liegen?



  • Barney Gumble schrieb:

    Das Problem liegt bei m_lpDevice. Wenn ich die Variable beim Funktionsaufruf als Parameter übergebe funktioniert alles einwandfrei. Wenn ich aber die Variable in einer anderen Funktion erst als Parameter übergebe, dann als Member-Variable abspeichere und dann mit einer anderen Funktion auf die abgespeicherte Variable zugreife, funktioniert es auf einmal nicht mehr. Woran kann das liegen?

    du machst irgendwo einen fehler.
    vermutlich kommst du mit zeigern nicht klar und aenderst irgendwo eine kopie des zeigers statt den zeiger selber.

    debugger helfen hier enorm.



  • Ist es als 3D-/Spieleprogrammierer eigentlich Pflicht C++ zu vergewaltigen wo es nur geht?

    Schreibt mal sauberes C++, dann musst du dich auch nicht mit solch komischem Verhalten herumärgern.



  • Tippgeber schrieb:

    Ist es als 3D-/Spieleprogrammierer eigentlich Pflicht C++ zu vergewaltigen wo es nur geht?

    Schreibt mal sauberes C++, dann musst du dich auch nicht mit solch komischem Verhalten herumärgern.

    Das Problem ist, dass die meisten Leute mit 3D Programmierung anfangen bevor sie die Sprache gelernt haben. Nur sind das dann eben 2 enorm komplexe Gebiete die man gleichzeitig lernen muss - da kommt dann halt sowas raus.

    Was natuerlich furchtbar ist, weil die meisten Leute so am ende weder das eine noch das andere richtig koennen aber irgendwie dennoch spiele hinnudlen koennen.

    Das problem ist aber auch, dass die meiste literatur zu diesem thema einfach nur grottig ist.



  • @Shade Of Mine: Ich ändere die Variable nicht. Ich speichere sie nur ab, und greife dann darauf zu.



  • Barney Gumble schrieb:

    @Shade Of Mine: Ich ändere die Variable nicht. Ich speichere sie nur ab, und greife dann darauf zu.

    Du machst etwas falsch. Das ist Fakt. Die Fehlermeldung deutet daraufhin dass du den Zeiger nicht aenderst sondern nur eine Kopie davon. Irgendwann musst du den Zeiger ja initialisieren, oder?

    Aber du solltest auch nicht rumraten oder rumraten lassen, sondern deinen Debugger nehmen und schritt fuer schritt durch den code durchsteppen und immer schauen ob der zeiger den richtigen wert hat.

    als kleiner tipp:
    du wuerdest dir unendlich viel leichter tun wenn du zuerst die grundlagen lernen wuerdest. denn gerade zeiger sind am anfang nicht ganz trivial zu verstehen und wenn man sie verstanden hat, dann fasst man sie sowieso fast nie wieder roh an...


Anmelden zum Antworten