Access violation lista

0

Witam, mam problem dotyczący odczytywania danych z listy.

Mając taki kod, dokładnie przy inicjalizacji pętli, dostaję wyjątek pochodzący z pliku "list", który mówi "Access violation reading location: 0xCDCDCDCD

std::string Entity::checkName(std::string& childName)
{
    for (const auto& child : mChildren) //<--except
    {
        if (child->mName == childName);
        //childName=someFuncHere
    }
return childName
}

Załączam też nagłówkowy:

class Entity
{
public:
	using EntityPtr = std::unique_ptr<Entity>;
 
	Entity(EntityType, PopHead::Base::GameData*, std::string name);
 
	virtual void input();
	virtual void update(sf::Time delta);
 
	void addChild(EntityPtr);
	void removeChild(const std::string& name);
	void removeChild(Entity* pointerToChildWhichIsSupposedToBeRemoved);
 
	auto getParent() const -> Entity& { return *mParent; }
	auto getName() const -> const std::string& { return mName; }
	auto getChild(std::string name) const->Entity&;
private:

std::string checkName(std::string&);
 
protected:
	Base::GameData* mGameData;
 
	const EntityType mEntityType;
	std::string mName;
 
	Entity* mParent;
	std::list< std::unique_ptr<Entity> > mChildren;
};

Nie wiem co może powodować problem, zastanawiałem się chwilę już ze znajomymi, ale nic ciekawego nie wymyśliliśmy. Thanks from the mountain ;D

0

0xCDCDCDCD taką wartość w trybie debug kompilator nadaje zmiennym, które nie mają w kodzie wartości nadanej.
Czyli twój kod używa wskaźnika, którego wartość nigdy nie została ustawiona (nawet na null).
Zakładam, że chodzi o wskaźnik this bo wyłożyło się na pierwszej linijce metody.
Czyli zmienna o nienadanej wartości znajduje się w kodzie wywołującym metodę Entity::checkName (sprawdź okienko "Call Stack") i musi być to kod nie obsługiwany przez std::unique_ptr (bo ten zawsze jest domyślnie ustawiany na null).

0

Dziękuję ;) To dość mocno naprowadziło mnie na problem, ale nadal mimo, że zidentyfikowałem co jest jego przyczyną, nie wiem jak go naprawić. Otóż problem występuje przy wskaźniku mParent, który zgodnie z konstruktorem powinien być zainicjalizowany nullptr'em, ale gdy przejadę debuggerem, to linijka ta jest tak jakby pomijana.

Entity::Entity(PopHead::World::EntityType type, PopHead::Base::GameData* gameData, std::string name)
:
 mParent(nullptr) // <------
,mEntityType(type)
,mGameData(gameData)
,mName(checkName(name))

Ta linijka nie jest w ogóle wykonywana, ale jeśli tylko nie będę używał funkcji checkName i jako argument przekażę samo name, to wszystko działa poprawnie i mParent dostaje NULL.

1

Konstruktor mChildren jeszcze się nie wykonał w momencie gdy wołasz checkName. Próbujesz użyć niezainicjowanego obiektu. Dlatego się wywaliło, jakiś wskaźnik wewnątrz klasy list jest śmieciowy.

Kolejność inicjalizacji pol klasy zależy od kolejności ich deklaracji w klasie, niezależnie od kolejności na liście inicjalizacyjnej. mChildren jest ostatnie.
Analogicznie z mParrent, dlatego nie widziałeś nullptr, jeszcze nie nastała jego kolej.

PS. Jakbyś od razu wrzucił więcej kodu, to odpowiedź miałbyś szybciej. Tutaj problem był z konstrukcją obiektu, a Ty akurat postanowiłeś pominąć konstruktor w kodzie, który pokazałeś. Wrzuciłeś dopiero potem, by pochwalić się swoim znaleziskiem, podczas gdy problem był tuż obok... Lekcja na przyszłości.

0

Zresztą po co wołać w konstruktorze checkName skoro wiadomo, że obiekt na początku jest bezdzietny.

1 użytkowników online, w tym zalogowanych: 0, gości: 1