[Allegro] Programmabsturz
-
Hallo liebe Spieleprogrammierer

Letzens habe ich das Programmieren mit Allegro angefangen und hatte auch keine Probleme damit eine abgewandelte Pong-Variante zu programmieren. Jetzt aber habe ich das Problem, dass mein neues Prog. an einer bestimmten Stelle, die ich schon ausfindig gemacht habe abstürzt, obwohl ich keinen Fehler entdecken kann. Deswegen poste ich mal nur die relevanten Stellen.
blaster.h
// Gegner (Basis: Spiel) class Gegner : Spiel { public: Gegner(); ~Gegner(); void initGegner(); Gegner gegnerSetzen( int anzahl ); void gegnerLoeschen( Gegner *gegner ); void zeichneGegner(); }; // KLASSE: GEGNER ~ENDE~blaster.cpp
Gegner Gegner::gegnerSetzen( int anzahl ) { Gegner *gegner = new Gegner[anzahl]; // dynamisches Array for( int i = 0; i < anzahl; i++ ) { gegner[i].initGegner(); // Gegner "i" initialisieren gegner[i].zeichneGegner(); // Gegner "i" zeichnen } return *gegner; // Um später alles wieder löschen zu können. (Löschen einzelner Gegner auch möglich...) }; void Gegner::zeichneGegner() // ZEICHNE { rectfill( buffer, position_x - GEGNER_BREITE, position_y, position_x + GEGNER_BREITE, position_y + GEGNER_HOEHE, WEISS ); Spiel::aufBildschirm(); // ausgeben }; void Gegner::initGegner() { do { position_y = 20; // OBEN position_x = rand() % ( 640 - GEGNER_BREITE ) + ( 0 + GEGNER_BREITE ); // zufällige X-KOORDINATE }while( besetzt[position_x][position_y] == true ); // Ist die Position bereits besetzt? besetzt[position_x][position_y] = true; // Position ist nun besetzt. }; void Gegner::gegnerLoeschen( Gegner *gegner ) { delete[] gegner; };main.cpp
Gegner *temp = NULL; Gegner feind; *temp = feind.gegnerSetzen( 5 );Jedes mal, wenn es zu der Stelle mit dem Setzen der Gegner kommt stürzt es ab. Liegt es eventuell an der Speicherverwaltung? Wenn ich die exe manuell starten will kommt aufjeden Fall der Fehler: "R6010 - abort() has been called"
EDIT: hatte was vergessen
-
Chroma schrieb:
[cpp]Gegner Gegner::gegnerSetzen( int anzahl )
{
...
return *gegner;
};ist das wirklich so gewollt?
[cpp] Gegner *temp = NULL;
Gegner feind;
*temp = feind.gegnerSetzen( 5 );[/cpp]worauf zeigt temp waehrend du die variabel reinkopierst? das ist sicherlich nicht gewollt.
schau dir nochmal ein tutorial zu pointern an

-
rapso schrieb:
ist das wirklich so gewollt?
ups, da gibt er ja die variable und nicht die adresse zurück. habe es gerade mal mit "&" versucht, aber das lässt er nicht zu (Konvertierung des Parameters 1 von 'Gegner **' in 'const Gegner &' nicht möglich)
rapso schrieb:
worauf zeigt temp waehrend du die variabel reinkopierst? das ist sicherlich nicht gewollt.
ich habe temp doch vorher auf NULL zeigen lassen? Danach soll es eigentlich auf das Gegner Array zeigen.
Ich denke mein Problem liegt darin, dass ich gar keine Adresse returne, sondern durch Dereferenzierung die Daten aus der Stelle des Speichers. Aber wie kann ich die Funktion so abändern, dass er die Adresse zurückgibt?
-
ich koennte dir zwar hier reinkopieren was in tutorials steht, aber ich glaube da bist du effektiver beim googlen

-
Dieser Thread wurde von Moderator/in rapso aus dem Forum Spiele-/Grafikprogrammierung in das Forum C++ verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Ich glaube, dass mein Fehler doch woanders liegen muss. Habe es korrigiert und es hat immer noch nicht geklappt, habe es sogar mit einem vector versucht.
Habe jetzt Testweise eifnach eine Schleife in die Main geschrieben.
Gegner feind[10]; for( int i = 0; i <= 5; i++ ) { feind[i].initGegner(); feind[i].zeichneGegner(); }auch mit dieser simplen Schleife tritt das Problem auf. Rufe ich "initGegner()" und "zeichneGegner()" ohne Schleife auf gibt es keine Probleme. Eine der beiden Funktionen scheint mit Schleifen nicht klarzukommen oder was kann noch falsch sein?
Beim Debuggen wirft es mich an die Zeile 99 der Datei "chkstk.asm":
test dword ptr [eax],eax ; probe page.
-
welche werte hat GEGNER_BREITE und wie gross ist "besetzt"
versuch mal statt [..] mit at(..) zu arbeiten, falls du dabei ueberindizierst, wird er an dieser stelle stehen bleiben.
-
#define GEGNER_BREITE 10 ... bool besetzt[BS_BREITE][BS_HOEHE]; // Besetzt-Feldalso besetzt[640][480], aber das dürften doch nur um die 35kb sein, da es bool werte sind oder habe ich mich da verrechnet?
das mit dem at habe ich schon in meinem code stehen, da ich es jetzt auf vectoren geändert habe. deswegen wirft er mich an diese besagte zeile 99. habe es auch nochmal in der main geändert und komme dann ebenfalls dorthin.
-
Also, ich habe aufjeden Fall einen Stack Overflow, aber ich finde die Stelle nicht. Das besetzt Array ist nicht dran Schuld. Irgendwie muss ich durch die Schleife eine unendliche Rekursion oder was Ähnliches entstehen lassen.

EDIT: Die Schleife habe ich jetzt zum Funktionieren gebracht.
vector<Gegner> feind; for( int i = 0; i <= 5; i++ ) { textout( screen, font, "VOR INIT", 242, 220, WEISS ); rest( 4000 ); feind.push_back( Gegner() ); feind.at( i ).initGegner(); textout( screen, font, "NACH INIT", 242, 240, WEISS ); textout( screen, font, "VOR ZEICHNE", 242, 260, WEISS ); feind.at( i ).zeichneGegner(); textout( screen, font, "NACH ZEICHNE", 242, 280, WEISS ); }Jedoch funktioniert es mit der setzeGegner(anzahl); Funktion immer noch nicht.
void Gegner::setzeGegner( int anzahl ) { vector<Gegner> gegner; // Vector for( int i = 0; i < anzahl; i++ ) { gegner.push_back( Gegner() ); gegner.at( i ).initGegner(); // Gegner "i" initialisieren gegner.at( i ).zeichneGegner(); // Gegner "i" zeichnen } };
-
Chroma schrieb:
Jedoch funktioniert es mit der setzeGegner(anzahl); Funktion immer noch nicht.
was funktioniert denn nicht?
die funktioen an und für sich sieht jedenfalls ok aus.
auch, wenn es alles ein wenig komisch gemacht ist(und kommentare wie // Vector genau so sinnvoll sind, wie.. da fällt mir nicht mal was ein -.-)//schon mal an und für sich nen komischer name - wie wäre es mit "erzeugeGegner" oder so was? void Gegner::setzeGegner( int anzahl ) { vector<Gegner> gegner; for( int i = 0; i < anzahl; i++ ) { //so hier ists besser: // gegner.push_back( Gegner() ); // gegner.back().initGegner(); // gegner.back().zeichneGegner(); //so hattest du es: // gegner.at( i ).initGegner(); // Gegner "i" initialisieren // gegner.at( i ).zeichneGegner(); // Gegner "i" zeichnen //so würd ichs machen: Gegner to_add; to_add.initGegner(); //so ne init-Funktion braucht man eigtl nie - dafür ist der Konstruktor da to_add.zeichneGegner(); gegner.push_back(to_add); } //gegner wird hier zerstört -> Funktion macht nicht wirklich was, oder? }bb
-
ja, das mit dem init stimmt schon, aber die aufgeschriebene version ist schon älter und dann hatte ich das so übernommen, aber das ist ja keine große sache das noch abzuändern.
der gegner wird übrigens nicht zerstört, ist mir schon selber aufgefallen und habe es als membervariable deklariert:).
funktion sieht im moment übrigens so aus ( mit deiner kleinen verbesserung):
void Gegner::setzeGegner( int anzGegner ) { for( int i = 0; i < anzGegner; i++ ) { Gegner neu; neu.initGegner(); neu.zeichneGegner(); gegner.push_back( neu ); } };werde berichten inwiefern es damit geht
EDIT:
Die Klasse Gegner sieht nun so aus:
// Gegner (Basis: Spiel) ------------------------------------------------------------------------------------- int Gegner::anzahl = 0; // Gegneranzahl Gegner::Gegner() { do { gegner_y = 30; // OBEN gegner_x = rand() % ( BS_BREITE - GEGNER_BREITE ) + ( 0 + GEGNER_BREITE ); // zufällige X-KOORDINATE }while( besetzt[gegner_x][gegner_y] == true ); // Ist die Position bereits besetzt? besetzt[gegner_x][gegner_y] = true; // Position ist nun besetzt. anzahl++; // Anzahl der Gegner um 1 erhöhen }; Gegner::~Gegner(){}; void Gegner::setzeGegner( int anzGegner ) { for( int i = 0; i < anzGegner; i++ ) { Gegner neuerGegner; neuerGegner.zeichneGegner(); gegner.push_back( neuerGegner ); } }; void Gegner::zerstoereGegner( int x, int y ) { int gegnerID; for( int i = 0; i < anzahl; i++ ) { if( ( gegner.at( i ).gegner_x == x ) && ( gegner.at( i ).gegner_y == y ) ) { gegnerID = i; break; } } gegner.erase( gegner.begin() + ( gegnerID - 1 ) ); anzahl--; // Anzahl um 1 Gegner verringern }; void Gegner::zeichneGegner() // ZEICHNE { rectfill( buffer, gegner_x - GEGNER_BREITE, gegner_y, gegner_x + GEGNER_BREITE, gegner_y + GEGNER_HOEHE, WEISS ); Spiel::aufBildschirm(); // ausgeben }; // KLASSE: GEGNER ~ENDE~ -------------------------------------------------------------------------------------Das Programm stürzt schonmal nicht mehr ab. Jedoch zeichnet er jetzt nur einen Gegner anstatt zum Beispiel 5
