Map in Klasse gibt Zugriffsverletzung aus
-
Hallo liebe Community,
ihr habt mir bisher immer sehr geholfen, einfach indem ich hier Antworten auf meine Fragen gefunden habe, ohne sie selbst stellen zu müssen. Ich find das Forum hier echt toll und muss euch aber leider nun auch mal mit einer Frage nerven.
Und zwar kommt es bei mir zu folgendem Fehler:
Unbehandelte Ausnahme bei 0x00cc7493 in Test.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000004.Das deutet ja eigentlich immer auf einen Nullpointer oder sowas hin allerdings, verwende ich an der betroffenen stelle nichtmal einen Pointer.
Ich zeig euch einfach mal den Code:
ObjectManager.h
struct Quad{ inline void RenderQuad( float fX, float fY, float fZ, float fSizeX, float fSizeY, float fSizeZ, int iTexture, TextureManager *pTextureManager ){ pTextureManager->RenderTexture( iTexture ); glBegin( GL_QUADS ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( fX-fSizeX, fY-fSizeY, 0.0f ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( fX+fSizeX, fY-fSizeY, 0.0f ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( fX+fSizeX, fY+fSizeY, 0.0f ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( fX-fSizeX, fY+fSizeY, 0.0f ); glEnd(); }; inline void RenderQuad( float fX, float fY, float fZ, float fSizeX, float fSizeY, float fSizeZ, int iAnimation, bool bSingleAnimation, TextureManager *pTextureManager ){ pTextureManager->RenderAnimation( iAnimation ); if( bSingleAnimation ){ glBegin( GL_QUADS ); pTextureManager->BindAnimation_Single( iAnimation, false, false ); glVertex3f( fX-fSizeX, fY-fSizeY, 0.0f ); pTextureManager->BindAnimation_Single( iAnimation, true, false ); glVertex3f( fX+fSizeX, fY-fSizeY, 0.0f ); pTextureManager->BindAnimation_Single( iAnimation, true, true ); glVertex3f( fX+fSizeX, fY+fSizeY, 0.0f ); pTextureManager->BindAnimation_Single( iAnimation, false, true ); glVertex3f( fX-fSizeX, fY+fSizeY, 0.0f ); glEnd(); }else{ glBegin( GL_QUADS ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( fX-fSizeX, fY-fSizeY, 0.0f ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( fX+fSizeX, fY-fSizeY, 0.0f ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( fX+fSizeX, fY+fSizeY, 0.0f ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( fX-fSizeX, fY+fSizeY, 0.0f ); glEnd(); } }; }; struct ModelTexture{ std::string strModelName; TextureManager *pTextureManager; int iTexture; }; struct ModelAnimation{ std::string strModelName; TextureManager *pTextureManager; int iAnimation; bool bSingleAnimation; }; struct ObjectBody{ std::string strBodyName; ModelTexture *pMTexture; ModelAnimation *pMAnimation; bool bIsAnimated; bool bIsDestructable; bool bIsMoveable; bool bIsCollisionable; }; struct ObjectInstance{ std::string strObjectName; ObjectBody *pObjectBody; Vector vPosition; Vector vSize; Vector vVelocity; Vector vAcceleration; }; class ModelManager{ private: ModelTexture *pModelTexture[128]; ModelAnimation *pModelAnimation[128]; TextureManager *pTextureManager; std::map< std::string, int > mstriModel; std::map< std::string, int >::iterator mstriIter; public: ModelManager(); ModelManager( TextureManager &cTextureManager ); ~ModelManager(); inline ModelTexture* GetModelTexture( std::string strModelName ){ return pModelTexture[ 0 ]; }; inline ModelAnimation* GetModelAnimation( std::string strModelName ){ return pModelAnimation[ 0 ]; }; void AddModel( std::string strModelName, std::string strPath, std::string strPrefix, std::string strSuffix, int iNumber ); void AddModel( std::string strModelName, std::string strData, int iNumber, float fAnimationRows, float fAnimationCols ); void AddModel( std::string strModelName, std::string strFilePath ); }; class BodyManager{ private: ObjectBody *pObjectBody[128]; bool bObjectBody[128]; ModelManager *pModelManager; std::map< std::string, int > mstri; std::map< std::string, int >::iterator mstriIter; public: BodyManager(); BodyManager( ModelManager &cModelManager ); ~BodyManager(); inline ObjectBody* GetObjectBody( std::string strObjectBodyName ){ mstriIter = mstri.find( strObjectBodyName ); ///// Wenn der find-Befehl ausgeführt werden soll, kommts zum Crash ///////////////////////////////////////////////////////////////////// if( mstriIter != mstri.end() ){ return pObjectBody[ mstriIter->second ]; } //return NULL; return pObjectBody[ 0 ]; }; int SearchEmptyObjectBody(); void AddObjectBody( std::string strObjectBodyName, std::string strModelName, bool bIsAnimated, bool bIsDestructable, bool bIsMoveable, bool bIsCollisionable ); }; class ObjectManager{ private: ObjectInstance *pObjectInstance[512]; bool bObjectInstance[512]; BodyManager *pBodyManager; Quad sQuad; public: ObjectManager(); ObjectManager( BodyManager &cBodyManager ); ~ObjectManager(); int SearchEmptyObjectInstance(); void AddObjectInstance( std::string strObjectName, std::string strObjectBodyName, float fPosX, float fPosY, float fPosZ, float fSizeX, float fSizeY, float fSizeZ ); void MoveObject( float fTime ); void RenderObject(); };Und hier ist noch die passende cpp-Datei.
ObjectManager.cpp
ModelManager::ModelManager(){ pTextureManager = NULL; } ModelManager::ModelManager( TextureManager &cTextureManager ){ pTextureManager = &cTextureManager; } ModelManager::~ModelManager(){ } void ModelManager::AddModel( std::string strModelName, std::string strPath, std::string strPrefix, std::string strSuffix, int iNumber ){ pModelAnimation[ 0 ] = new ModelAnimation(); pModelAnimation[ 0 ]->pTextureManager = pTextureManager; pModelAnimation[ 0 ]->strModelName = strModelName; pModelAnimation[ 0 ]->iAnimation = pTextureManager->AddAnimation( strPath, strPrefix, strSuffix, iNumber ); pModelAnimation[ 0 ]->bSingleAnimation = false; } void ModelManager::AddModel( std::string strModelName, std::string strData, int iNumber, float fAnimationRows, float fAnimationCols ){ mstriModel.insert( std::make_pair( strModelName, iNumber ) ); pModelAnimation[ 0 ] = new ModelAnimation(); pModelAnimation[ 0 ]->pTextureManager = pTextureManager; pModelAnimation[ 0 ]->strModelName = strModelName; pModelAnimation[ 0 ]->iAnimation = pTextureManager->AddAnimation_Single( strData, iNumber, fAnimationRows, fAnimationCols ); pModelAnimation[ 0 ]->bSingleAnimation = true; } void ModelManager::AddModel( std::string strModelName, std::string strFilePath ){ pModelTexture[ 0 ] = new ModelTexture(); pModelTexture[ 0 ]->pTextureManager = pTextureManager; pModelTexture[ 0 ]->strModelName = strModelName; pModelTexture[ 0 ]->iTexture = pTextureManager->AddTexture( strFilePath ); } /////////////////////////////////////////////////// BodyManager::BodyManager(){ for( uint uiLoop = 0; uiLoop < 512; uiLoop++ ){ pObjectBody[ uiLoop ] = NULL; bObjectBody[ uiLoop ] = false; } pModelManager = NULL; } BodyManager::BodyManager( ModelManager &cModelManager ){ for( uint uiLoop = 0; uiLoop < 512; uiLoop++ ){ pObjectBody[ uiLoop ] = NULL; bObjectBody[ uiLoop ] = false; } pModelManager = &cModelManager; } BodyManager::~BodyManager(){ } inline int BodyManager::SearchEmptyObjectBody(){ for( uint uiLoop = 0; uiLoop < 512; uiLoop++ ){ if( bObjectBody[ uiLoop ] == false ){ bObjectBody[ uiLoop ] = true; return uiLoop; } } return 0; } void BodyManager::AddObjectBody( std::string strObjectBodyName, std::string strModelName, bool bIsAnimated, bool bIsDestructable, bool bIsMoveable, bool bIsCollisionable ){ int iNumber = SearchEmptyObjectBody(); if( iNumber == 0 ){ } mstri.insert( std::make_pair( strObjectBodyName, iNumber ) ); ///// Wenn der Insert-Befehl ausgeführt werden soll, kommts zum Crash ///////////////////////////////////////////////////////////////////// pObjectBody[ iNumber ] = new ObjectBody(); pObjectBody[ iNumber ]->strBodyName = strObjectBodyName; pObjectBody[ iNumber ]->bIsAnimated = bIsAnimated; pObjectBody[ iNumber ]->bIsDestructable = bIsDestructable; pObjectBody[ iNumber ]->bIsMoveable = bIsMoveable; pObjectBody[ iNumber ]->bIsCollisionable = bIsCollisionable; if( bIsAnimated ){ pObjectBody[ iNumber ]->pMAnimation = pModelManager->GetModelAnimation( strModelName ); }else{ pObjectBody[ iNumber ]->pMTexture = pModelManager->GetModelTexture( strModelName ); } } ///////////////////////////////////////////////////////// ObjectManager::ObjectManager(){ for( uint uiLoop = 0; uiLoop < 512; uiLoop++ ){ pObjectInstance[ uiLoop ] = NULL; bObjectInstance[ uiLoop ] = false; } pBodyManager = NULL; } ObjectManager::ObjectManager( BodyManager &cBodyManager ){ for( uint uiLoop = 0; uiLoop < 512; uiLoop++ ){ pObjectInstance[ uiLoop ] = NULL; bObjectInstance[ uiLoop ] = false; } pBodyManager = &cBodyManager; } ObjectManager::~ObjectManager(){ } inline int ObjectManager::SearchEmptyObjectInstance(){ for( uint uiLoop = 0; uiLoop < 512; uiLoop++ ){ if( bObjectInstance[ uiLoop ] == false ){ bObjectInstance[ uiLoop ] = true; return uiLoop; } } return NULL; } void ObjectManager::AddObjectInstance( std::string strObjectName, std::string strObjectBodyName, float fPosX, float fPosY, float fPosZ, float fSizeX, float fSizeY, float fSizeZ ){ int iNumber = SearchEmptyObjectInstance(); if( iNumber == NULL ){ } pObjectInstance[ iNumber ] = new ObjectInstance(); pObjectInstance[ iNumber ]->strObjectName = strObjectName; pObjectInstance[ iNumber ]->vPosition.X = fPosX; pObjectInstance[ iNumber ]->vPosition.Y = fPosY; pObjectInstance[ iNumber ]->vPosition.Z = fPosZ; pObjectInstance[ iNumber ]->vSize.X = fSizeX; pObjectInstance[ iNumber ]->vSize.Y = fSizeY; pObjectInstance[ iNumber ]->vSize.Z = fSizeZ; pObjectInstance[ iNumber ]->vVelocity = 0; pObjectInstance[ iNumber ]->vAcceleration = 0; pObjectInstance[ iNumber ]->pObjectBody = pBodyManager->GetObjectBody( strObjectBodyName ); } void ObjectManager::MoveObject( float fTime ){ for( uint uiLoop = 0; uiLoop < 512; uiLoop++ ){ if( bObjectInstance[ uiLoop ] ){ pObjectInstance[ uiLoop ]->pObjectBody->pMAnimation->pTextureManager->UpdateAnimation( fTime, pObjectInstance[ uiLoop ]->pObjectBody->pMAnimation->iAnimation ); } } } void ObjectManager::RenderObject(){ for( uint uiLoop = 0; uiLoop < 512; uiLoop++ ){ if( bObjectInstance[ uiLoop ] ){ sQuad.RenderQuad( pObjectInstance[ uiLoop ]->vPosition.X, pObjectInstance[ uiLoop ]->vPosition.Y, pObjectInstance[ uiLoop ]->vPosition.Z, pObjectInstance[ uiLoop ]->vSize.X, pObjectInstance[ uiLoop ]->vSize.Y, pObjectInstance[ uiLoop ]->vSize.Z, pObjectInstance[ uiLoop ]->pObjectBody->pMAnimation->iAnimation, pObjectInstance[ uiLoop ]->pObjectBody->pMAnimation->bSingleAnimation, pObjectInstance[ uiLoop ]->pObjectBody->pMAnimation->pTextureManager ); } } }Der Fehler bei mstri.insert tritt immer auf wenn ich die Funktion AddObjectBody aufrufe, wenn ich die insert-Funktion ausklammere dann tritt bei GetObjectBody ein ähnlicher Fehler auf und es will mstri.find nicht ausführen.
Wenn ich dem fehler nachgehe lande ich irgendwo in der xtree-datei.Was für mich allerdings am merkwürdigsten ist, dass wenn ich die map und den iterator in den beiden andern klassen deklarier ( die ja vom aufbau her sehr ähnlich sind, eigentlich kaum unterschiede haben ) und dann in den Funktionen
ModelManager::AddModel oder ObjectManager::AddObjectInstance den gleichen insert-Befehl aufrufe, funktioniert alles

Außerdem hab ich noch rausgefunden, dass, wenn ich im Konstruktor der BodyManager-Klasse den insert-Befehl aufrufe, dieser funktioniert, aber die Werte später nicht mehr vorhanden sind.Ich hab leider keine Ahnung wo mein Fehler liegt und es wäre nett wenn ihr mir helfen könntet. Falls ihr mehr Codestücke braucht einfach Bescheid sagen.
MfG
Pandoril
-
Pandoril schrieb:
Falls ihr mehr Codestücke braucht einfach Bescheid sagen.
Nein! Weniger! Bitte lies dir den dritten Link in meiner Signatur durch und konstruiere ein Minimalbeispiel.
-
SeppJ schrieb:
Pandoril schrieb:
Falls ihr mehr Codestücke braucht einfach Bescheid sagen.
Nein! Weniger! Bitte lies dir den dritten Link in meiner Signatur durch und konstruiere ein Minimalbeispiel.
Sicher, dass du nicht den zweiten meinst?
-
Auch wenn es nicht pädagogoisch ist:
sehe ich dort Arrays der Größe 128? Und Schleifen die diese Arrays bis 511 indexieren?Wenn Dein Compiler sie schon unterstützt nimm
std::begin()undstd::end(), oder einstd::array.
Sonst nutz einstatic int size=512;oder sonstwas, damit sowas nicht passiert.
-
Okey dann halt weniger
sorry ich weiss das warn bissl viel.Also das ist die Klasse wo die Map deklariert ist:
class BodyManager{ private: //..noch mehr Variablen std::map< std::string, int > mstri; std::map< std::string, int >::iterator mstriIter; public: BodyManager(); BodyManager( ModelManager &cModelManager ); ~BodyManager(); inline ObjectBody* GetObjectBody( std::string strObjectBodyName ){ mstriIter = mstri.find( strObjectBodyName ); ///// Wenn der find-Befehl ausgeführt werden soll, kommts zum Crash ///////////////////////////////////////////////////////////////////// if( mstriIter != mstri.end() ){ return pObjectBody[ mstriIter->second ]; } //return NULL; return pObjectBody[ 0 ]; }; //...ander Funktionen void AddObjectBody( std::string strObjectBodyName, std::string strModelName, bool bIsAnimated, bool bIsDestructable, bool bIsMoveable, bool bIsCollisionable );Und das ist die AddObjectBody-Funktion wo der Fehler stattfindet:
void BodyManager::AddObjectBody( std::string strObjectBodyName, std::string strModelName, bool bIsAnimated, bool bIsDestructable, bool bIsMoveable, bool bIsCollisionable ){ //..davor wird noch die iNumber abgefragt mstri.insert( std::make_pair( strObjectBodyName, iNumber ) ); ///// Wenn der Insert-Befehl ausgeführt werden soll, kommts zum Crash ///////////////////////////////////////////////////////////////////// pObjectBody[ iNumber ] = new ObjectBody(); // Das lass ich mal aus das sind nur Zuweisungen für das pObjectBody }Außerdem noch der Konstruktor bei dem der Insert-Befehl funktioniert:
BodyManager::BodyManager( ModelManager &cModelManager ){ mstri.insert( std::make_pair( "toller Name", 60 ) ); // die werte sind nur Beispiele for( uint uiLoop = 0; uiLoop < 512; uiLoop++ ){ pObjectBody[ uiLoop ] = NULL; bObjectBody[ uiLoop ] = false; } pModelManager = &cModelManager; }So ich hoffe das ist von der Länge her besser

-
Nee, das kann man jetzt ja nicht mehr ausführen. Das ist bei Laufzeitfehlern aber wichtig. Wir brauchen etwas ausführbares, aber möglichst weniger als 150 Zeilen. Ja, das ist Arbeit, ein Programm so weit zu reduzieren. Aber du möchtest ja auch Hilfe bekommen, weil du nicht mehr weiter weißt, da muss man schon mal was für tun. Es besteht auch eine sehr gute Chance, dass du dabei schon den Fehler findest, weil er auf einmal verschwindet, nachdem du etwas änderst. Dann weißt du, wo der Fehler wahrscheinlich sitzt. Das ist allgemein eine sehr gute Methode, um Fehler zu finden, daher solltest du es unbedingt üben (selbst wenn das was Furble Wurble genannt hat schon der Fehler gewesen sein sollte).
Neben den rohen Arrays sind in deinem Code sind noch mehr Sachen drin, die verdächtig sind. Vor allem die manuelle Speicherverwaltung, die in C++ unnötig ist und immer wieder zu Fehlern dieser Art führt. Aber ich und andere lesen nicht 400+ Zeilen Code, um genau auf den Fehler zeigen zu können. Da sagt man dann bloß, dass du die manuelle Speicherverwaltung rausnehmen solltest und hofft, dass darin wirklich der Fehler lag.
(Selbst wenn sich später herausstellen sollte, dass der Fehler woanders liegt, sind die Tipps mit den Arrays und der manuellen Speicherverwaltung natürlich trotzdem Sachen, die du auch umsetzen solltest)
-
So zuallererst erstmal danke an Furble Wurble
Da lag schon mein ganzer Fehler.
Als ich die Schleife dann nur bis 127 hab laufen lassen ging auch alles.
Also jetzt alles. Vielen Dank nochmal dafür und ich hoffe ich kann bei meiner nächsten Frage die Hinweise von SeppJ besser beachten und gleich besseren Codstücke schreiben.
Nur so als Frage gibts hier für das Forum auch ne Funktion wo ich den ganzen Code reinpacken könnte und dann ausklappen könnte? Halt wie sone Spoilerfunktion ( ich hoffe ihr wisst was ich meine )?
-
Pandoril schrieb:
Nur so als Frage gibts hier für das Forum auch ne Funktion wo ich den ganzen Code reinpacken könnte und dann ausklappen könnte? Halt wie sone Spoilerfunktion ( ich hoffe ihr wisst was ich meine )?
Nein, leider. Sollte es mal geben, wurde aber nie verwirklicht.