Vector in Array speichern
-
Hallo,
Ich versuche gerade einen Vector mit Pointern zu meinem eigenen Objekt zu erstellen, diesen Vector packe ich in ein Array:
std::vector<Piece*> m_allPieces[2];Das Problem ist, wenn ich mein Programm so kompiliere erhalte ich einen Memory Error und das ganze stürzt ab ^^
Wie soll ich das jetzt lösen? Vector in Vector???
Hab grade herausgefunden, dass das ganze gar nicht an dem Array liegt, wenn ich einen Vector deklariere im Header, stürzt das Program sofort ab... aber zum Beispiel ein Iterator funktioniert (Kann ihn schlecht benutzen oder einen vector xD)
Aber ich erhalte nun eine Fehlermeldung: (Windows Meldung)
Ausnahme: std::bad_alloc
hmm
-
Samyboy schrieb:
Ich versuche gerade einen Vector mit Pointern zu meinem eigenen Objekt zu erstellen, diesen Vector packe ich in ein Array:
Tönt kompliziert. Was willst du genau erreichen (was, nicht wie)?
-
Dein Fehler liegt nicht in der Verwendung von vector-Arrays an sich. Das ist kein Problem. Folglich machst du bei deren Verwendung irgendwas falsch.
-
SeppJ schrieb:
Dein Fehler liegt nicht in der Verwendung von vector-Arrays an sich. Das ist kein Problem. Folglich machst du bei deren Verwendung irgendwas falsch.
Nunja ich verwende mein Vector noch gar nirgends, ich deklariere ihn bloss im Header...
Ich werde versuchen eine genauere Fehlermeldung rauszubekommen ^^
-
Samyboy schrieb:
Nunja ich verwende mein Vector noch gar nirgends, ich deklariere ihn bloss im Header...
Dann liegt es sicher nicht daran. Zeige doch mal etwas Code.
Und es wäre gut, wenn du noch auf meine obere Frage eingehen könntest.
-
Nexus schrieb:
Samyboy schrieb:
Ich versuche gerade einen Vector mit Pointern zu meinem eigenen Objekt zu erstellen, diesen Vector packe ich in ein Array:
Tönt kompliziert. Was willst du genau erreichen (was, nicht wie)?
Nunja ich versuche alle meine Schachfiguren in ein Array von 2 Vectoren zu speichern (alle Weisse in m_allPieces[0] und alle Schwarzen in m_allPieces[1], weil WHITE und BLACK konstante 0 und 1 sind...)
Danach möchte ich sie einzeln ansprechen können, um die Position herauszufinden und so weiter...
Ich könnte natürlich mein "main-board" Array durchlaufen, aber da hab ich halt die Schwarzen und Weissen Figuren nicht getrennt...
-
Hab noch etwas herausgefunden, mein Programm stürzt nur ab, wenn ich 2 Objekte vom Typ Vector initialisiere, also z.B
2 vector<Piece*>
2 vector<Piece*>::iterator
1 vector<Piece*> und 1 vector<Piece*>::iteratorHier mal meine Board Klasse, die betroffen ist:
class Board { public: Board(); ~Board(); void Draw(sf::RenderWindow* window); bool MoveIsLegal(int move[2][2], unsigned int& player); void DoMove(int move[2][2]); void Reset(); void AddPiece(Piece* piece, int position[2]); Piece* GetPosition(int position[2]); // std::vector<Piece*> GetThreateningPieces(int position[2]); private: Piece* m_board[8][8]; std::vector<Piece*> m_allPiecesWhite; // std::vector<Piece*> m_allPiecesBlack; // Wenn das kein Kommentar ist stürzts ab! // std::vector<Piece*>::iterator iter; char m_boardWithLetters[8][8]; void DeletePiece(int position[2], int color); };Wenn ich sonst noch Code zeigen soll, bitte sagen! Bin echt dankbar für jede Hilfe, bin jetzt schon etwa ne Stunde dran :p
-
Das ist zwar grauenhaftes Design, aber an sich noch kein Fehler.
Meine Glaskugel sagt aber, dass du bestimmt was falsch machst bei der Pointerfrickelei.
Empfohlener Ansatz zur Problembehebung: Schmeiß alles weg. Überdenke dein Schachproblem. Mach ein neues, sauberes Design. -> Proft!
-
SeppJ schrieb:
Das ist zwar grauenhaftes Design, aber an sich noch kein Fehler.
Meine Glaskugel sagt aber, dass du bestimmt was falsch machst bei der Pointerfrickelei.
Empfohlener Ansatz zur Problembehebung: Schmeiß alles weg. Überdenke dein Schachproblem. Mach ein neues, sauberes Design. -> Proft!
Könnteste bitte konkret werden mit Design?
Ich habe das Gefühl das ÜBERHAUPT NICHTS lesbar ist bei meinem Schachprogramm, und ans neu machen hab ich auch schon gedacht ^^
-
Samyboy schrieb:
Könnteste bitte konkret werden mit Design?
Ja, wenn du mit deinen Anforderungen konkret wirst. Was soll das Programm denn können?
-
SeppJ schrieb:
Samyboy schrieb:
Könnteste bitte konkret werden mit Design?
Ja, wenn du mit deinen Anforderungen konkret wirst. Was soll das Programm denn können?
Naja, ich meinte was vom Design her schlecht ist bei dieser Klasse

Und noch etwas, komischerweise kann ich einen Vector deklarieren, auch ohne #include <vector>? (trotzdem können nicht mehrere vectoren deklariert werden (auch nicht in einem Array z.B), sonst stürzt das ganze ab) Ich glaube die SFML Library nervt da irgendwie die Vectoren oder so oO
Sehr, sehr komisch -.-
-
Die Fehlermeldung:
(Falls es jemanden was bringt, ich werde nicht schlau draus, leider keine Zeilen angegeben xD)
Eine Ausnahme (erste Chance) bei 0x778d3913 in SMFL.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x20202020. Eine Ausnahme (erste Chance) bei 0x778d3913 in SMFL.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x20202020. Eine Ausnahme (erste Chance) bei 0x778d3913 in SMFL.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x20202020. Eine Ausnahme (erste Chance) bei 0x76f3b727 in SMFL.exe: Microsoft C++-Ausnahme: std::bad_alloc an Speicherposition 0x0044f514.. Eine Ausnahme (erste Chance) bei 0x6780fd85 in SMFL.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00000000. Unbehandelte Ausnahme bei 0x6780fd85 in SMFL.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00000000
-
Samyboy schrieb:
SeppJ schrieb:
Samyboy schrieb:
Könnteste bitte konkret werden mit Design?
Ja, wenn du mit deinen Anforderungen konkret wirst. Was soll das Programm denn können?
Naja, ich meinte was vom Design her schlecht ist bei dieser Klasse

Wie du schon selbst schreibst, ist dein Programm praktisch unlesbar. Außerdem fuchtelst du ohne erkennbaren Grund mit rohen Pointern rum, was gerade bei unerfahrenen Programmierern fast immer schief geht, so auch bei dir. Ich werde mir mal kurz Gedanken machen wie ich ein Schachbrett mit deinen Methoden modellieren würde. Melde mich in ein paar Minuten wieder.
-
SeppJ schrieb:
Samyboy schrieb:
SeppJ schrieb:
Samyboy schrieb:
Könnteste bitte konkret werden mit Design?
Ja, wenn du mit deinen Anforderungen konkret wirst. Was soll das Programm denn können?
Naja, ich meinte was vom Design her schlecht ist bei dieser Klasse

Wie du schon selbst schreibst, ist dein Programm praktisch unlesbar. Außerdem fuchtelst du ohne erkennbaren Grund mit rohen Pointern rum, was gerade bei unerfahrenen Programmierern fast immer schief geht, so auch bei dir. Ich werde mir mal kurz Gedanken machen wie ich ein Schachbrett mit deinen Methoden modellieren würde. Melde mich in ein paar Minuten wieder.
Nunja, sollte man nicht möglichs jedes Objekt auf dem Heap speichern und dann die Pointer herumschicken?
-
Samyboy schrieb:
Nunja, sollte man nicht möglichs jedes Objekt auf dem Heap speichern und dann die Pointer herumschicken?
Nein, auf keinen Fall! Denk dran, Value-Semantik ist gut. Benutze möglichst automatische Objekte. Wenn du besitzende Zeiger brauchst, kapsle sie (Smart-Pointer, Pointer-Container oder ähnliches). Aber im Anwendungscode sollte
newunddeleteso wenig wie nur möglich auftauchen.
-
Hier ist mal ein Anfang, mit dem man arbeiten kann. Du musst nur noch die Methoden Implementieren, was in den meisten Fällen trivial sein sollte. Das schwierige, wo die Magie passiert, ist Coordinates::valid_move().
#include <vector> #include <cassert> enum Color{white, black}; enum Value{empty, pawn, knight, bishop, rook, queen, king}; // A set of coordinates on a chess board class Coordinates { private: unsigned rank, file; public: Coordinates(unsigned x, unsigned y): file(x), rank(y) { assert(x<8); assert(y<8); }; // Checks if other square is a valid move for a <v> from this coordinate: bool valid_move(Value v, Coordinates c) const; }; class Square { private: // What kind of piece is on the square? Value i_value; // The color of the piece on the square. Ignored if value is empty. Color i_color; public: Square(Value v, Color c=white): i_value(v), i_color(c){}; // Draw the piece on output void draw(sf::RenderWindow* window) const; void set(Value v, Color c=white); // Getter: Value get_piece(); Color get_color(); }; // A chessboard class Board { private: std::vector<Square> i_squares[64]; // Returns reference to square at coordinates Square& at(Coordinates c); public: // Draws a chessboard and calls draw for all squares void draw(sf::RenderWindow* window) const; // Set piece at position void AddPiece(Coordinates coordinates, Value v, Color c=white); // Check if move is legal for player bool MoveIsLegal(Coordinates from, Coordinates to, Color player) const; // Move a piece void DoMove(Coordinates from, Coordinates to); // Sets all squares to empty void Reset(); // Resets all squares to the initial value for a standard game void InitialPosition(); };
-
Bis auf
std::vector<Square> i_squares[64];ein (ganz) gutes Design.
SeppJ, du meinst wohl eher, daß der vector mit 64 Feldern (Square) initialisiert wird, und nicht, daß du 64 vectors erzeugst?
Und Coordinates::valid_move() wird ohne Zugriff auf das Schachbrett auch nicht sehr sinnvoll sein (d.h. z.B. bei Bauern und Königen ist auch die Farbe entscheidend).
Und ich würde auch noch die Trennung von GUI (SFML) und Logic (ChessBoard) vornehmen...
-
Samyboy schrieb:
Nunja, sollte man nicht möglichs jedes Objekt auf dem Heap speichern und dann die Pointer herumschicken?
Wenn ein Objekt erst einmal mit new angelegt wurde ist alles was von diesem Objekt ausgeht (Member) automatisch im Heap und nicht im Stack des Programms (des main-Funktionsaufrufes). Geht gar nicht anders. Nur wenn du etwas dann mit new anlegst ist es eben ein beliebiger Speicherbereich und nicht mehr zusammenhängend.
-
Wenn ich zum Design noch was anmerken dürfte:
Die Methoden Draw( ... ) gehören da eindeutig nicht zu Square und auch nicht zu Board, du solltest Logik und Darstellung trennen.
-
Th69 schrieb:
Bis auf
std::vector<Square> i_squares[64];ein (ganz) gutes Design.
SeppJ, du meinst wohl eher, daß der vector mit 64 Feldern (Square) initialisiert wird, und nicht, daß du 64 vectors erzeugst?
Ups, ähh, ja.
Und Coordinates::valid_move() wird ohne Zugriff auf das Schachbrett auch nicht sehr sinnvoll sein (d.h. z.B. bei Bauern und Königen ist auch die Farbe entscheidend).
Ich hatte mir gedacht, dass die Methode Board::MoveIsLegal() das macht und dabei Coordinates::valid_move() benutzt um überhaupt zu prüfen, wohin gegangen werden kann. Ist sicherlich noch suboptimal, da ich mir nicht wirklich Gedanken gemacht habe, wie man das implementieren würde.
Und ich würde auch noch die Trennung von GUI (SFML) und Logic (ChessBoard) vornehmen...
Ahh, die Urfrage der Spieleprogrammierung. Irgendwie konnte mir nie jemand sagen, welche Vorgehensweise besser ist (ich programmiere aber auch nicht viele Spiele). Ist momentan die Trennung von Logik und Darstellung wieder in?