Merkwürdiger Heap-Bug
-
Hallo Leute,
Warum funktioniert
CObject Surface; //sichtbares Objekt deklarieren, Surface.Init("surface.bmp", 0, 0); //initialisieren Video.LoadObject(Surface.GetpSprite(), Surface.GetpRect(), 0, 450); //und direkt in den Videospeicher laden
aber
if(lObjects.empty()) { CObject Surface; //sichtbares Objekt deklarieren, Surface.Init("surface.bmp", 0, 0); //initialisieren lObjects.push_back(Surface); //und zur Liste der Objekte hinzufügen } for(ilO = lObjects.begin(); ilO != lObjects.end(); ilO++) //Liste der Objekte abfragen { Video.LoadObject(ilO->GetpSprite(), ilO->GetpRect(), 0, 450); //iterator in den Videospeicher laden }
löst den Fehler "Unbehandelte Ausnahme bei 0x7759ea27 in Sidescroller.exe: 0xC0000374: Ein Heap wurde beschädigt." aus? (CObject hat einen Copy-Constructor)
Die aufgerufene Funktion ist übrigens
void CVideo::LoadObject(SDL_Surface *pSprite, SDL_Rect *pRect, int xPos, int yPos) { SDL_Rect *pScreenrect = new SDL_Rect; pScreenrect->w = pRect->w; pScreenrect->h = pRect->h; pScreenrect->x = xPos; pScreenrect->y = yPos; SDL_BlitSurface(pSprite, pRect, pScreen, pScreenrect); delete pScreenrect; pScreenrect = NULL; }
und benutzt die SDL. (Obwohl ich nicht denke, dass das Problem hier liegt.)
-
In welcher Zeile wird denn der Fehler geworfen?
Hat deine Klasse CObject einen funktionierenden Copy-Constructor?
MfG SideWinder
-
Ein paar Anmerkungen zum Code:
CObject Surface; //sichtbares Objekt deklarieren, Surface.Init("surface.bmp", 0, 0); //initialisieren
Hat es einen speziellen Grund, wieso du den Umweg über die Init-Funktion gehst, wenn du die Initialisierung gleich im Konstruktor vollziehen könntest?
SDL_Rect *pScreenrect = new SDL_Rect; // [...] delete pScreenrect; pScreenrect = NULL;
Die letzte Zeile ist vollständig unnötig, generell würde ich hier keine dynamische Speicherverwaltung verwenden. Nimm ein automatisches Objekt:
SDL_Rect screenRect;
for(ilO = lObjects.begin(); ilO != lObjects.end(); ilO++)
Gewöhn dir an, im Normalfall Präfix-Inkrementierungen wie
++ilO
zu verwenden. Du sparst dir damit in gewissen Fällen eine unnötige Kopie.
-
SideWinder schrieb:
In welcher Zeile wird denn der Fehler geworfen?
Hat deine Klasse CObject einen funktionierenden Copy-Constructor?
MfG SideWinder
Der Fehler tritt in Zeile 10 des dritten von mir geposteten Listings (LoadObject) auf. Der Copy-Constructor sollte funktionieren:
CObject::CObject(const CObject &rhs) { pSprite = new SDL_Surface; pRect = new SDL_Rect; *pSprite = *(rhs.pSprite); *pRect = *(rhs.pRect); }
Nexus schrieb:
Hat es einen speziellen Grund, wieso du den Umweg über die Init-Funktion gehst, wenn du die Initialisierung gleich im Konstruktor vollziehen könntest?
Ich will selbst bestimmen, wann das Object initialisiert wird (so kann ich z.B. ggf. das Sprite ändern) und will nicht, dass die Klasse rumzickt wenn ich nicht sofort Constructor-Argumente angebe.
Nexus schrieb:
Die letzte Zeile ist vollständig unnötig, generell würde ich hier keine dynamische Speicherverwaltung verwenden.
Du hast natürlich recht!
Nexus schrieb:
Gewöhn dir an, im Normalfall Präfix-Inkrementierungen wie ++ilO zu verwenden. Du sparst dir damit in gewissen Fällen eine unnötige Kopie.
Das wusste ich nicht, danke!
Ok das wusste ich nicht.