2009-07-27 16 views
2

Ich bin über ein seltsames Problem gestolpert, in dem ich nicht verstehen kann. Ich bin kein Experte bei C/C++, also ertragen Sie mit mir. Ich habe eine NSC-Klasse, die von einer Player-Klasse abgeleitet ist, die von einer Sprite-Klasse abgeleitet ist. Die Sprite-Klasse enthält eine setupAnimation-Funktion, die ein Array von Floats mit Koordinaten auf der Textur zuweist, jedes Element des Arrays bezieht sich auf ein Animations-Frame. Das ist alles gut und funktioniert gut.Speicherzuteilung Crash

Ein Problem tritt jedoch auf, wenn ich der NSC-Klasse ein Array von Zeigern hinzufüge. Diese Zeiger sind vom Typ "Item". Wenn ich dieses Array hinzufüge, funktioniert es gut, wenn das Array klein ist (10 war die Größe, die ich getestet habe), wird aber abstürzen, wenn das Float-Array für zuvor erwähnte Texturkoordinaten zugewiesen wird, wenn die Größe etwas größer ist (100 war die Größe I) geprüft).

Hier sind einige Code-Fragmente zeigt das Material die ich oben erwähnt:

der Item-Klasse Array von Zeigern:

engItem* itsLoot[100]; // With 100 here, the crash occurs as shown below 

Die Texturkoordinaten und deren Zuordnung Pendants:

GLfloat* itsTextureXData; 
    GLfloat* itsTextureYData; 

    ... 

    animationFile >> frameCount; // Tested, the value is correct 

    engDeallocate(getTextureXData(), true); // Works fine 
    itsTextureXData = new GLfloat[frameCount]; // This is where the crash occurs 

    engDeallocate(getTextureYData(), true); 
    itsTextureYData = new GLfloat[frameCount]; 

Diese Code-Fragment ist die Basis jeder Klasse, die von der Sprite-Klasse abgeleitet ist. Was ich nicht verstehen kann ist, warum ein extra 90 Zeiger ein Problem während der Float-Zuweisung verursacht. Nur ein bisschen Software-Informationen mit diesen

OS zu gehen: Windows Vista 32-bit, Compiler: Visual C++ 9.0, Programmlaufzeit Speicher: ~ 17,600k, Systemspeicher: ~ 2GB

In diesem Sinne, Ich kann nicht sehen, dass Speicher leer ist, und ich kann nicht nachvollziehen, wie ein Array von Zeigern dazu führt, dass die Zuweisung fehlschlägt. Wie erwähnt, funktioniert die Zuweisung in allen anderen Klassen gut, die von Sprite abgeleitet sind (sowie von Sprite selbst), aber sobald dieser Zeigerbereich der NPC-Klasse hinzugefügt wird, weist der NPC dieses Strukturdaten-Fließkommarray nicht mehr zu, ohne abzustürzen.

+0

Was ist der Absturz? Das heißt, was ist der Callstack und Ausnahmecode oder Assert, wenn verfügbar? – MSN

Antwort

3

Die von Ihnen beschriebenen Symptome sind typisch für ein beschädigtes Speicherzuweisungssystem. Die Tatsache, dass der Fehler auftritt, wo Sie es sagen, ist wahrscheinlich nicht signifikant - der wahre Fehler ist fast sicher woanders.

Es gibt viele Möglichkeiten, um die Chancen dafür zu reduzieren, aber die große Gefahr, ist Code in C++ zu schreiben, nicht C mit etwas C++ Syntax. Verwenden Sie Sammlungen wie std :: vector, die ihre eigene Speicherverwaltung ausführen, anstatt selbst zu versuchen.

6

Irgendwo anders in Ihrem Programm, haben Sie wahrscheinlich eine Art von Speicherfehler (schrieb über das Ende eines Arrays, schrieb in freigegebenen Speicher, etc.). In diesem Fall ist es möglich, dass Sie Strukturen überschreiben, die vom Speicherzuweisungssystem verwendet werden, sodass es bei der nächsten Zuweisung abstürzt. Es kann helfen, Ihr Programm mit einem Tool wie Valgrind zu starten, um den Fehler zu finden. EDIT: Ich habe gerade festgestellt, dass Sie Windows verwenden und Valgrind funktioniert nur unter Linux. Wenn Ihr Code portabel genug ist, ist es relativ einfach, Linux und Valgrind zu testen. Wenn das nicht möglich ist, siehe Is there a good Valgrind substitute for windows? auf SO. (Leider sieht es so aus, als wären die meisten kommerziell, nicht frei und Open Source wie Valgrind.)

Der beste Weg, dies zu vermeiden, ist die Verwendung von C++ - Sammlungen wie std::vector oder std::list anstelle von Arrays. Wenn Sie diese Sammlungen verwenden, stellen Sie sicher, dass Sie den Kopiervorgang auf ein Minimum beschränken (verwenden Sie z. B. const Referenzen als Parameter und nicht Kopien des ursprünglichen Objekts, wenn Sie es nicht ändern usw.)), oder du wirst sehr schlechte Leistung bekommen (und es sieht so aus, als ob du ein Spiel machst, also ist das wichtig).

+1

Vielen Dank für die schnelle Antwort. Ich beziehe mich so viel wie möglich schon. Ich werde den Vektor öfter verwenden, aber ich habe immer die Bibliotheken verpönt, die tun, was ich selbst machen kann, da sie auf eine Weise aufgebaut sind, die ich nicht mag. Es ist die Basis eines schlechten Programmierers, den ich kenne, und ich werde höchstwahrscheinlich davon wachsen. Nochmals vielen Dank, sehr geschätzt (sowie dank Neil oben). –

+1

Ich würde diese Änderung jetzt beginnen. Das Rad neu zu erfinden ist schrecklich. Was ist mit ihnen ist nicht Setup, wie Sie möchten? – GManNickG

0

Wie bereits gesagt, sieht dies sehr nach Speicherkorruption aus.

Um einzugrenzen, wo sich der tatsächliche Fehler befindet, führen Sie im Debugmodus aus, und versuchen Sie, die Häufigkeit zu erhöhen, mit der der CRT den Heap auf Beschädigung überprüft.

Der folgende Code aus dem MSDN genommen zeigt, wie die CRT-Überprüfung jeder 1024 statt alle 16 Heap-Operationen lassen:

#include <crtdbg.h> 
int main() 
{ 
int tmp; 

// Get the current bits 
tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 

// Clear the upper 16 bits and OR in the desired freqency 
tmp = (tmp & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF; 

// Set the new bits 
_CrtSetDbgFlag(tmp); 
} 

Weitere Informationen finden Sie _CrtSetDbgFlag in MSDN