C++ Zugriffsrecht Verletzung

02/10/2013 04:57 Kosic#1
Hey Leute,

Ich habe ein Problem mit "Zugriffsrechten".
Quote:
Unbehandelte Ausnahme bei 0x76f715de in Universe_Area official.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000010.
Laut Compiler ist die Funktion "Stone.draw_Enemy();" schuld.

Das ist der Code:
main
Code:
#include <Windows.h>
#include "Randomizer.h"
#include "Window.h"
#include "Player.h"
#include "Sound.h"

int main()
{
	/*
        CODE
        */
	
	Enemy Stone;
	sf::Texture TStone = Stone.define_Enemy( "***/****/****.png" );
	sf::Sprite *SStone;

	sf::RenderWindow App( sf::VideoMode( 806, 600, 32 ), "Universe Area       Alpha 1.2.2.0", sf::Style::Titlebar );
	App.setFramerateLimit( 60 );
	WindowEvent wEvent;

	/*
        CODE
        */

	while( App.isOpen() )
	{
		/*
                CODE
                */

		SStone = Stone.spawn_Enemy( TStone, 30, 30 );


		App.clear( sf::Color( 0, 0, 0 ) );
		/*
                CODE
                */
		Stone.draw_Enemy( App, SStone );
		App.display();
	}

	return 0;
}
Player.h
Code:
#include <SFML/Graphics.hpp>
#include <string>
#include <list>
#include "Randomizer.h"

/*
CODE
*/

/*****-GEGNERKLASSE-*****/
class Enemy
{
	private:
		sf::Texture TEnemy;
		float CenterX;
		float CenterY;

		sf::Clock SpawnTimer;
		std::list<sf::Sprite>EnemyListe;
		std::list<sf::Sprite>::iterator EnemyIt;

	public:
		sf::Texture define_Enemy( const std::string TexturePfad );
		sf::Sprite* spawn_Enemy( sf::Texture &sTEnemy, const int TextureX, const int TextureY );
		void draw_Enemy( sf::RenderWindow &Window, sf::Sprite *dSEnemy );
};
/*****-GEGNERKLASSE-*****/
Player.cpp
Code:
#include "Player.h"

//-------------------------------------------------------------------------------------------------// **BEGIN**
//-------------------------------------------------------------------------------------------------// **BEGIN**
//-------------------------------------------------------------------------------------------------// **BEGIN**

sf::Texture Enemy::define_Enemy( const std::string TexturePfad )
{
	TEnemy.loadFromFile( TexturePfad );

	return TEnemy;
}

sf::Sprite* Enemy::spawn_Enemy( sf::Texture &sTEnemy, const int TextureX, const int TextureY )
{
	CenterX = ( TextureX / 2);
	CenterY = ( TextureY / 2);

	if( true )
	{
		if( SpawnTimer.getElapsedTime() > sf::seconds( 0.2 ) )
		{
			sf::Sprite *ESprite;
			ESprite = new sf::Sprite;
			ESprite->setTexture( sTEnemy );
			ESprite->setPosition( int_Randomizer( 20, 770 ), -50 );
			ESprite->setOrigin( CenterX, CenterY );

			EnemyListe.push_back( *ESprite );

			SpawnTimer.restart();

			return ESprite;
		}
	}
}

void Enemy::draw_Enemy( sf::RenderWindow &Window, sf::Sprite *dSEnemy )
{
	for(EnemyIt = EnemyListe.begin(); EnemyIt != EnemyListe.end(); EnemyIt++)
	{
		dSEnemy->move( 0, 5 );
		
		Window.draw( *dSEnemy );

		//Gegner löschen bei ungültiger Y-Position
		if( EnemyIt->getPosition().y > 660 )
		{
			EnemyListe.erase( EnemyIt );
			EnemyIt = EnemyListe.begin();
		}

	}
}

//-------------------------------------------------------------------------------------------------// **END**
//-------------------------------------------------------------------------------------------------// **END**
//-------------------------------------------------------------------------------------------------// **END**
Mfg,
Kosic

PS: Bitte vergebt mir, wenn ichs einfach gerade Übersehe oder ein Stück Code vergessen habe zu posten. Es ist schon spät und ich bin müde. Gute Nacht!
02/10/2013 06:00 Dr. Coxxy#2
Enemy::spawn_Enemy returnt nicht immer nen wert - meckert der compiler da nicht eh schon rum?
wie auch immer, nachdem die erste textur hinzugefügt wurde returnt spawn_Enemy i-nen mist, woraufhin in draw_enemy auf nen ungültigen pointer zugegriffen wird.
02/10/2013 13:41 yihaaa#3
warum macht man sowas wie
Code:
if( true )
sieht das cooler aus?
02/10/2013 13:50 Schlüsselbein#4
Wäre nicht schlecht, wenn du dein Problem auf das wesentliche enschränken würdest. Nicht jeder hat Lust, die Klassen einzeln auseinander zu nehmen.
Das Problem ist doch auch sicher in ein paar Zeilen reproduzierbar.
02/10/2013 14:08 Dr. Coxxy#5
Quote:
Originally Posted by yihaaa View Post
warum macht man sowas wie
Code:
if( true )
sieht das cooler aus?
macht man normalerweise wenn dort noch ein check reinkommt, der zu dem zeitpunkt aber noch nicht implementiert ist, einfach damit mans nachher einfacher wiederfindet, bzw. man dran denkt.

Quote:
Originally Posted by Schlüsselbein View Post
Wäre nicht schlecht, wenn du dein Problem auf das wesentliche enschränken würdest. Nicht jeder hat Lust, die Klassen einzeln auseinander zu nehmen.
Das Problem ist doch auch sicher in ein paar Zeilen reproduzierbar.
was hast du denn, er hats doch schon auf das nötigste reduziert?
und wie gesagt, wahrscheinliches problem hab ich oben schon beschrieben.

@TE:
der visual studio debugger kann zeilenweise im C++ code durchsteppen und laufzeitvariablen anzeigen.
das sollte helfen, das problem in zukunft selbst zu lösen.
02/10/2013 15:26 Kosic#6
Quote:
Originally Posted by Dr. Coxxy View Post
macht man normalerweise wenn dort noch ein check reinkommt, der zu dem zeitpunkt aber noch nicht implementiert ist, einfach damit mans nachher einfacher wiederfindet, bzw. man dran denkt.
True. Denn später kommt dort die Abfrage rein ob Leben != 0 sind.

Mfg,
Kosic
02/10/2013 15:37 Dr. Coxxy#7
und?
Quote:
Enemy::spawn_Enemy returnt nicht immer nen wert - meckert der compiler da nicht eh schon rum?
wie auch immer, nachdem die erste textur hinzugefügt wurde returnt spawn_Enemy i-nen mist, woraufhin in draw_enemy auf nen ungültigen pointer zugegriffen wird.
war das der fehlerverursacher?
02/10/2013 15:41 Kosic#8
Bin gerade am rum Probieren.

#Edit
Wenn ich den Code so lasse und in der Main die draw_Enemy() Funktion auskommentiere, bekomme ich keine Fehler mehr. Ich frage mich nur, wie das Problem fixen kann, da es ja eine Liste ist und ich direkt mit den Variablen arbeiten muss. Deswegen immer bei den Übergabeparametern ein '&' vor dem Parameter. Also muss ich was returnen damit ich den Sprite in der draw_Enemy() Funktion wieder Übergeben kann.

Mfg,
Kosic
02/10/2013 16:40 Dr. Coxxy#9
was passiert wenn bei der funktion:

Code:
sf::Sprite* Enemy::spawn_Enemy( sf::Texture &sTEnemy, const int TextureX, const int TextureY )
{
	CenterX = ( TextureX / 2);
	CenterY = ( TextureY / 2);

	if( true )
	{
		if( SpawnTimer.getElapsedTime() > sf::seconds( 0.2 ) )
		{
			sf::Sprite *ESprite;
			ESprite = new sf::Sprite;
			ESprite->setTexture( sTEnemy );
			ESprite->setPosition( int_Randomizer( 20, 770 ), -50 );
			ESprite->setOrigin( CenterX, CenterY );

			EnemyListe.push_back( *ESprite );

			SpawnTimer.restart();

			return ESprite;
		}
	}
}
das hier:
Code:
if( SpawnTimer.getElapsedTime() > sf::seconds( 0.2 ) )
false ergibt?
es wird etwas zufälliges returnt.

hier(in der mainschleife):
Code:
SStone = Stone.spawn_Enemy( TStone, 30, 30 );
wird SStone also etwas zufälliges zugewiesen.
damit rufst du dann draw_enemy auf(auch in der mainschleife):
Code:
Stone.draw_Enemy( App, SStone );
in draw_enemy wird dann
Code:
dSEnemy->move( 0, 5 );
aufgerufen.
dSEnemy zeigt in dem moment ins nix und erzeugt obige access violation.

und bitte schau dir an, wie der vs debugger funktioniert, bzw. lern die sprache, sowas hat man normalerweise in 1 minute aufgespürt.
02/10/2013 17:30 Kosic#10
Oh mein Gott. Ich bin so dumm sorry... Fehler gefunden:

Hatte ganz vergessen, dass der Iterator eh in der Klasse ist und ich den eigentlich benutzen sollte :facepalm:
02/11/2013 00:20 MrSm!th#11
Quote:
Enemy::spawn_Enemy returnt nicht immer nen wert - meckert der compiler da nicht eh schon rum?
Nein, VS gibt dazu nur eine Warnung aus, die dir bei sonst erfolgreichen Compile-Vorgängen nicht auffallen bzw. ausgegeben werden, solange du Warnungen nicht als Fehler werten lässt.