Probleme mit std::vector
-
Hi,
ich hab ein Problem mit dem std::vector. Ich verwende den MSVC6...aber erstmal hier meine situation:ich verwende einen std::vector:
std::vector<oscProgramHeader*> m_pProgramTemplates;
später fülle ich den Vektor mit Daten - ungefähr so:
oscProgramHeader* pNewProg = new oscProgramHeader(); m_pProgramTemplates.push_back(pNewProg);
Das ganze steht in einer Schleife und funktioniert einmal fehlerfrei. Beim zweiten mal kommt es dann zu einer Zugriffsverletzung beim Aufruf von push_back. Außerdem hab ich per Debugger festgestellt, dass der Aufruf von size() nach dem ersten Aufruf von push_back 0 zurückliefert, obwohl er doch 1 zurückgeben sollte.
Der Aufruf von push_back vergrößert doch den Vector automatisch, oder?
Weiß jemand, woran das liegen könnte? Steh ich auf dem Schlauch oder ist das mal wieder ein bug im MSVC??? Vielen Dank schon mal im Voraus...
Mfg, smasher1985
-
der gezeigte code ist in ordnung. der fehler liegt woanders
-
@woanders: Ich weiß, dass der Code fehlerfrei ist, deshalb wundert mich das seltsame Verhalten meines Vectors auch um so mehr. Warum das seltsame Verhalten von size()??? Und in welchen Fällen kann push_back überhaupt zu einer Zugriffsverletzung führen? Was könnte ich falsch gemacht haben? Jedenfalls kann ich nach unzähligen Debug-Sessions garantieren, dass da Programm genau mit dieser Zeile abbricht und mir eine Zugriffsverletzung entgegenschmeißt.
Weitere Ideen?
Mfg, smasher1985
-
du kannst dir zum beispiel mit überschreitung einer array-grenze oder ähnlichen dingern dein ganzes kaputt schießen, so dass auch solche fehler passieren können.
-
vielleicht sollte ich noch mal genauer beschreiben, was ich beim Debuggen rausgefunden habe:
Also beim zweiten Aufruf von push_back kommt es zu einer Zugriffsverletztung - und zwar in der Datei XMEMORY, die im Verzeichnis ..\VC98\include des MSVC6 liegt. Die Stelle, die die Zugriffsverletzung verursacht, ist die dritte Zeile des folgenden Codes:
template<class _T1, class _T2> inline void _Construct(_T1 _FARQ *_P, const _T2& _V) {new ((void _FARQ *)_P) _T1(_V); }
Vielleicht bringt das ja irgend jemanden auf die zündende Idee? *hoff*
Ich verzweifel nämlich echt an diesem Problem.@styles: ich kann keine überschreitung von array-grenzen oder ähnliches finden, der code lief bisher eigenltich fehlerfrei
Mfg, smasher1985
-
Jo das bringt mich auf ne Zündende Idee
Zeig mal bitte etwas mehr Quellcode.
-
ok, ok - noch ein Versuch
Der Fehler liegt mit Sicherheit in dieser Funktion, denn wenn ich diese auskommentiere, funktioniert alles fehlerfrei. Hier also die komplette Funktion:
// load a script collection bool omeScriptManager::Load( const std::string& strFileName ) { FILE* inputFile = fopen(strFileName.c_str(), "rb"); omeLog::Get().Write(LOG_APP, "Loading script file ", strFileName.c_str()); m_strCurrentScriptFile = strFileName; char* pCodeSegment = 0; omeHashMap<std::string, oscFunctionHeader *>* pFunctionList = new omeHashMap<std::string, oscFunctionHeader*>(); oscStackItem* pConstantPool = 0; unsigned char c; do { c = readChar(inputFile); if (c==FUNCTION_ID) { oscFunctionHeader* pNewFunc = new oscFunctionHeader(); std::string strFunctionName = readString(inputFile); pNewFunc->m_strName = strFunctionName; pNewFunc->m_cInputs = readByte(inputFile); pNewFunc->m_cOutputs = readByte(inputFile); pNewFunc->m_cLocalLimit = readByte(inputFile); pNewFunc->m_nStackLimit = readUInt16(inputFile); pNewFunc->m_nStartCode = readInt32(inputFile); pNewFunc->m_nEndCode = readInt32(inputFile); // add to function table pFunctionList->put(strFunctionName, pNewFunc); omeLog::Get().Write(LOG_APP, "Loaded function '%s'", pNewFunc->m_strName.c_str()); } else if (c==PROGRAM_ID) { oscProgramHeader* pNewProg = NULL; pNewProg = new oscProgramHeader(); if (pNewProg==NULL) omeLog::Get().Write(LOG_APP, "ERROR: not enough memory"); std::string strProgramName = readString(inputFile); pNewProg->m_strName = strProgramName; pNewProg->m_cLocalLimit = readByte(inputFile); pNewProg->m_nStackLimit = readUInt16(inputFile); pNewProg->m_cTriggerType = readByte(inputFile); pNewProg->m_strTriggerArgument = readString(inputFile); pNewProg->m_nStartCode = readUInt32(inputFile); pNewProg->m_nEndCode = readUInt32(inputFile); // add a new input watch entry if neccessary if ((pNewProg->m_cTriggerType == TRIGGER_ON_KEYDOWN) || (pNewProg->m_cTriggerType == TRIGGER_ON_KEYSTILLDOWN) || (pNewProg->m_cTriggerType == TRIGGER_ON_KEYUP) || (pNewProg->m_cTriggerType == TRIGGER_ON_KEYSTILLUP)) omeInputTask::AddInputWatchEntry((int)pNewProg->m_cTriggerType, pNewProg->m_strTriggerArgument); // add to list of templates m_pProgramTemplates.push_back((oscProgramHeader*)pNewProg); // PROBLEM PROBLEM PROBLEM PROBLEM omeLog::Get().Write(LOG_APP, "%i", m_pProgramTemplates.size()); // nur zum DEBUGGEN omeLog::Get().Write(LOG_APP, "Loaded program '%s'", pNewProg->m_strName.c_str()); } else if (c==CONSTANTS_ID) { unsigned int nNumConsts = readUInt32(inputFile); omeLog::Get().Write(LOG_APP, "Loading %i constants", nNumConsts); // create the constant pool pConstantPool = new oscStackItem[nNumConsts]; for (unsigned int i=0; i<nNumConsts; ++i) { char cType = readChar(inputFile); switch (cType) { case INT_CONST: pConstantPool[i].m_nVal = readInt32(inputFile); omeLog::Get().Write(LOG_APP, "Read constant int: %i", pConstantPool[i].m_nVal); break; case FLOAT_CONST: pConstantPool[i].m_fVal = readFloat(inputFile); omeLog::Get().Write(LOG_APP, "Read constant float: %f", pConstantPool[i].m_fVal); break; case STRING_CONST: pConstantPool[i].m_strVal = readString(inputFile); omeLog::Get().Write(LOG_APP, "Read constant string: %s", pConstantPool[i].m_strVal.c_str()); break; default: omeLog::Get().Write(LOG_APP, "ERROR - unknown constant type '%i'", cType); break; } } } else if (c==CODE_ID) { unsigned int nCodeSize = readUInt32(inputFile); pCodeSegment = new char[nCodeSize]; omeLog::Get().Write(LOG_APP, "Loading %i bytes of code", nCodeSize); fread(pCodeSegment, sizeof(char), nCodeSize, inputFile); } } while (pCodeSegment==0); omeLog::Get().Write(LOG_APP, "DONE"); fclose(inputFile); m_pVM = new omeVirtualScriptMachine(pCodeSegment, pFunctionList, pConstantPool); // cause TRIGGER_ON_INIT trigger Trigger(TRIGGER_ON_INIT); return true; }
Ich hoffe das reicht jetzt an code...
Danke für die Mühe...
Mfg, smasher1985
-
OK, ich bin noch auf eine weitere Seltsamkeit gestoßen. Dazu muss ich euch aber noch mal ein wenig Code präsentieren
Im Konstruktor meiner Singleton-Klasse habe ich den Vector jetzt mal testweise auf die Größe 10 eingestellt.class omeScriptManager : public omeSingleton<omeScriptManager> { private: std::vector<oscProgramHeader*> m_pProgramTemplates; // ... public: omeScriptManager() : m_pVM(0), m_nGameState(0) { m_pProgramTemplates.resize (10); } bool Load( const std::string& strFileName ); // ... };
Mein Singleton wird dann so initialisiert:
new omeScriptManager(); omeScriptManager::GetSingleton().Load("helloWorld.osc");
In der Funktion Load lass ich mir jetzt gleich am Anfang die Größe des Vectors liefern und in eine Logdatei schreiben:
omeLog::Get().Write(LOG_CLIENT, "%i", m_pProgramTemplates.size());
Dubioserweise schreibt das eine 0 in die logdatei und nicht - wie zu erwarten wäre - eine 10.
Woran liegt das? Ich bin wirklich mit meinem Latein am Ende...
Mfg, smasher1985