Zugriffsverletzung beim Lesen an Position ...



  • Hallo.

    Weil mir mein alter Thread mitlerweile zu groß ist und das hier was völlig anderes ist, habe ich einen neuen Thread aufgemacht. Es handelt sich um das selbe Grundthema wie im anderen.

    Mein Problem:

    Ich rufe mit ...->setID(20); eine Funktion auf. In dieser wird der Instanz eine neue ID zugewiesen. Wenn ich jetzt das Programm ausführe, das stürzt es an dieser Stelle ab! Wenn ich das im Debbuging-Modus mache, dann erhalte ich an dieser Stelle die Meldung:

    Unbehandelte Ausnahme bei 0x00413458 in Map.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x2c62f35c.
    

    Der eigentliche Fehler tritt hier auf:

    if(tmp != Block::ID)
    

    Wobei der Fehler ganz genau bei Block::ID auftritt.

    Wenn ich aber vorher die Klasse in meine Konsole ausgebe (ich habe dafür den operator überladen...), dann geht das fehlerfrei!

    Kann mir da jemand helfen?????

    Ich weiß garnicht was ich tun soll.

    P.S.: Wenn ihr mehr Code braucht, einfach sagen.
    P.P.S.: Die Adrrese ist immer gleich!



  • Warum ist ID denn ein statischer Member, macht das irgendwie Sinn, dass alle Blöcke die gleiche ID haben? oO



  • Nein, ID ist kein statischer Member.

    Das Problem tritt auch auf, wenn ich this->ID mache!



  • Die erinnerung schrieb:

    if(tmp != Block::ID)
    

    Wobei der Fehler ganz genau bei Block::ID

    Äähm für Klassenname::Member müsste der Member eigentlich statisch sein...

    Zeig am besten mal deine Blockklasse.



  • Block.h:

    #include "Block_Data.h"
    #include <map>
    #include "Block_ID.h"
    #include <iostream>
    
    #pragma once
    
    std::map<Block_ID, Block_Data> input();
    
    class Block
    {
    private:
    	static std::map<Block_ID, Block_Data> data;
    	Block_ID ID;
    	bool Updated;
    
    public:
    	Block();
    	~Block();
    
    	void setID(unsigned int ID);
    	void setID(unsigned int ID, unsigned int Sub_ID);
    	void setID(Block_ID ID);
    
    	unsigned int get_ID() const;
    	unsigned int get_Sub_ID() const;
    	Block_ID get_Block_ID() const;
    	Block_Data get_data() const;
    
    	bool updated();
    
    	friend std::ostream& operator<<(std::ostream& Stream, const Block block);
    	friend std::ostream& operator<<(std::ostream& Stream, const Block* block);
    };
    

    Block.cpp:

    #include "Block.h"
    #include <string>
    
    std::map<Block_ID, Block_Data> Block::data;
    
    Block::Block()
    {
    	if(Block::data.empty())
    	{
    		Block::data = input();
    	}
    
    	Block::Updated = true;
    }
    
    Block::~Block()
    {
    }
    
    void Block::setID(unsigned int ID)
    {
    	Block_ID tmp = Block_ID(ID);
    
    	if(tmp != Block::ID)
    	{
    		Block::Updated = true;
    		Block::ID = tmp;
    	}
    }
    
    void Block::setID(unsigned int ID, unsigned int Sub_ID)
    {
    	Block_ID tmp = Block_ID(ID, Sub_ID);
    
    	if(tmp != Block::ID)
    	{
    		Block::Updated = true;
    		Block::ID = tmp;
    	}
    }
    
    void Block::setID(Block_ID ID)
    {
    	if(ID != Block::ID)
    	{
    		Block::Updated = true;
    		Block::ID = ID;
    	}
    }
    
    unsigned int Block::get_ID() const
    {
    	return Block::ID.ID;
    }
    
    unsigned int Block::get_Sub_ID() const
    {
    	return Block::ID.Sub_ID;
    }
    
    Block_ID Block::get_Block_ID() const
    {
    	return Block::ID;
    }
    
    Block_Data Block::get_data() const
    {
    	return Block::data[Block::ID];
    }
    
    bool Block::updated()
    {
    	bool tmp = Block::Updated;
    	Block::Updated = false;
    
    	return tmp;
    }
    
    std::ostream& operator<<(std::ostream& Stream, const Block block)
    {
    	return Stream << "ID:\t\t\t" << block.get_Block_ID() << "\n"
    		<< "Undurchsichtig:\t\t" << ((block.get_data().get_opaque()) ? "Ja" : "Nein") << "\n"
    		<< "Solide:\t\t\t" << ((block.get_data().get_solid()) ? "Ja" : "Nein") << "\n"
    		<< "Textur-ID:\t\t" << block.get_data().get_texture() << "\n\n";
    }
    
    std::ostream& operator<<(std::ostream& Stream, const Block* block)
    {
    	return Stream << "ID:\t\t\t" << block->get_Block_ID() << "\n"
    		<< "Undurchsichtig:\t\t" << ((block->get_data().get_opaque()) ? "Ja" : "Nein") << "\n"
    		<< "Solide:\t\t\t" << ((block->get_data().get_solid()) ? "Ja" : "Nein") << "\n"
    		<< "Textur-ID:\t\t" << block->get_data().get_texture() << "\n\n";
    }
    
    std::map<Block_ID, Block_Data> input()
    {
    	std::map<Block_ID, Block_Data> data;
    
    	Block_Data tmp;
    
    	tmp = Block_Data();			//ID: 0
    	data[Block_ID(0)] = tmp;
    
    	tmp = Block_Data();			//ID: 1
    	tmp.set_opaque(true);
    	tmp.set_texture(1);
    	data[Block_ID(1)] = tmp;
    
    	tmp = Block_Data();			//ID: 2
    	tmp.set_opaque(true);
    	tmp.set_solid(true);
    	tmp.set_texture(2);
    	data[Block_ID(2)] = tmp;
    
    	tmp = Block_Data();			//ID: 5
    	tmp.set_solid(true);
    	tmp.set_texture(2568);
    	data[Block_ID(5)] = tmp;
    
    	return data;
    }
    


  • Ich würde dir raten statt Block::ID auf jeden Fall this zu benutzen kann sein ,dass der Fehler dann trotzdem in der Funktion passiert allerdings wahrscheinlich nur weil durch das hier Block::ID irgendwo ein Speicherfehler passiert



  • nö!

    Hab gerade alles ausprobiert. Alle nicht statischen Variablen mit this-> statt Block:: gemacht, da wo's eindeutig ist sogar weggelassen!

    Immer der gleiche Fehler.



  • Kannst du den Code von Block_ID reinstellen pls



  • Hier:

    Block_ID.h:

    #include <iostream>
    
    #pragma once
    
    class Block_ID
    {
    public:
    	unsigned int ID;
    	unsigned int Sub_ID;
    
    	Block_ID();
    	Block_ID(unsigned int ID);
    	Block_ID(unsigned int ID, unsigned int Sub_ID);
    
    	~Block_ID();
    
    	bool operator< (Block_ID data) const;
    	bool operator== (Block_ID data) const;
    	bool operator!= (Block_ID data) const;
    
    	friend std::ostream& operator<<(std::ostream& Stream, const Block_ID Block);
    	friend std::ostream& operator<<(std::ostream& Stream, const Block_ID* Block);
    };
    

    Block_ID.cpp:

    #include "Block_ID.h"
    
    Block_ID::Block_ID()
    {
    	Block_ID::ID = 0;
    	Block_ID::Sub_ID = 0;
    }
    
    Block_ID::Block_ID(unsigned int ID)
    {
    	Block_ID::ID = ID;
    	Block_ID::Sub_ID = 0;
    }
    
    Block_ID::Block_ID(unsigned int ID, unsigned int Sub_ID)
    {
    	Block_ID::ID = ID;
    	Block_ID::Sub_ID = Sub_ID;
    }
    
    Block_ID::~Block_ID()
    {
    }
    
    bool Block_ID::operator< (Block_ID data) const
    {
    	if(Block_ID::ID == data.ID)
    	{
    		return Block_ID::Sub_ID < data.Sub_ID;
    	}
    
    	return Block_ID::ID < data.ID;
    }
    
    bool Block_ID::operator== (Block_ID data) const
    {
    	return (Block_ID::ID == data.ID) && (Block_ID::Sub_ID == data.Sub_ID);
    }
    
    bool Block_ID::operator!= (Block_ID data) const
    {
    	return (Block_ID::ID != data.ID) || (Block_ID::Sub_ID != data.Sub_ID);
    }
    
    std::ostream& operator<<(std::ostream& Stream, const Block_ID Block)
    {
    	if(Block.Sub_ID == 0)
    	{
    		return Stream << Block.ID;
    	}
    
    	return Stream << Block.ID << "." << Block.Sub_ID;
    }
    
    std::ostream& operator<<(std::ostream& Stream, const Block_ID* Block)
    {
    	if(Block->Sub_ID == 0)
    	{
    		return Stream << Block->ID;
    	}
    
    	return Stream << Block->ID << "." << Block->Sub_ID;
    }
    


  • Das sieht ok aus nur diese Zeile wirkt nen bisschen merkwürdig

    Block_ID tmp = Block_ID(ID);
    

    Erstell tmp lieber mal so

    Block_ID tmp(ID);
    

    und versuchs dann nochmal bin mir net sicher obs funzt aber versuchen schadet nicht



  • Und nein, das hat nichts geändert

    Bei Debugging ist an der Fehlerstelle folgende Variablen füllung:

    ID	28145	unsigned int
    -		this	0x2c62f358 {ID={...} Updated=??? }	Block * const
    +		data	[4](({ID=0 Sub_ID=0 }, {solid=false opaque=false texture=0 }),({ID=1 Sub_ID=0 }, {solid=false opaque=true texture=1 }),({ID=2 Sub_ID=0 }, {solid=true opaque=true texture=2 }),({ID=5 Sub_ID=0 }, {solid=true opaque=false texture=2568 }))	std::map<Block_ID,Block_Data,std::less<Block_ID>,std::allocator<std::pair<Block_ID const ,Block_Data> > >
    -		ID	{ID=??? Sub_ID=??? }	Block_ID
    		[b]ID	CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden[/b]	
    		[b]Sub_ID	CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden[/b]	
    		[b]Updated	CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden[/b]	
    +		tmp	{ID=28145 Sub_ID=0 }	Block_ID
    


  • tmp wird ja richtig intialisiert, der Fehler muss somit im vorhandenen sein.
    Wäre es möglich ein Update Funktion zu machen sie muss nichts tun, das einzige was der überladene ostream operator macht ist werte ausgeben er verändert ja nichts.Also wäre meine Idee einfach eine leere friend Funktion vorher aufzurufen um zu schauen ob der "richtige" Block angesprochen wird.

    void Prove(const Block b)
    {
    b.ID=b.ID;
    b.Sub_ID=b.Sub_ID;
    }
    


  • Das Löst zwar (vieleicht) das Problem, aber dir Ursache ist es nicht!

    P.S.: Nein, es geht nicht!



  • Das stimmt nicht du rufst in deinem Quelltext Block::ID auf im Quelltext gibts es zwei Blocks woher soll der Compiler denn wissen welcher gemeint ist?



  • Ich hab jetzt Alle Block:: durch this-> erstetzt (außer bei Block::data) und in Block_ID das selbe.

    Es geht nicht!



  • .< Hmm dann weiß ich auch nicht weiter tut mir leid 😞



  • Hantierst du irgendwo im Gesamt-Code mit Zeigern? Zugriffsverletzung ... klingt nämlich nach uninitalisiertem Zeiger oder Zugriff auf bereits freigegebenem Speicher.



  • versuch doch mal alles soweit wie möglich zu vereinfachen, so dass man ein kompilierbares minimalbeispiel bekommt, wo der fehler noch auftritt



  • erstens. Nein, zeiger verwende ich eigenetlich nicht.

    Und ein Kompilerbares Beispiel zu geben ist schwer.

    Ich könnte euch die ganze Projektmappe als .zip hochladen. Ich verwende microsoft visual C++ 2010.

    Denn ich vermute fast, es könnte an den gut 32 mio. Blöcken liegen.

    Aber mal sehen.

    Wollt ihr es es als zip?



  • hmm gerne stells rein und ich schaue mal ob es bei mir läuft



  • Die erinnerung schrieb:

    erstens. Nein, zeiger verwende ich eigenetlich nicht.

    Was jetz? Ja oder nein. "eigentlich nicht" ist etwas zu schwammig.

    Das Programm kannst du gerne mal hochladen.
    Aber zu den 32 Mio Blöcken hätt ich mal noch eine Frage: Befinden die sich permanent im Speicher? Auch wenn das Problem dadurch vielleicht nicht ausgelöst wird (müsste man mal mit weniger testen) solltest du keine 32 Mio. im Speicher halten. Stückweise auslagern in Dateien (= Chunk-Managment) wäre vielleicht eine resourcenschonende Lösung.
    BTW, da du Minecraft anscheinend "klonen" willst empfehle ich dir mal den Minecraft-Code anzuschauen. Ist zwar Java, wirkt aber recht vertraut (mit der Ausnahme, dass ich überall "new" und kein einziges mal "delete" lese 😉 )


Anmelden zum Antworten