Problem z std::vector.

Problem z std::vector.
ZP
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 2 lata
  • Postów:12
0

Witam!
Nowy dzień nowe problemy, dzisiaj mam problem dla was pewnie trywialny, dla mnie nie taki oczywisty. Z góry mówię że głowiłem się nad tym cały wczorajszy dzień, szukałem po różnych forach i rzeczy typu konstruktor kopiujący nie działały, na stackoverflow też nie widziałem nic co by mi pomogło.
Mam klasę abstrakcyjną która się nazywa "Turret":

Kopiuj
#pragma once
#include <SFML\Graphics.hpp>

class Turret : sf::Drawable
{
public:
	Turret() {};
	Turret(int, int) {};
	virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const = 0;
	virtual void Attack()=0;
	virtual float GetRange()=0;

protected:
	int Damage;
	float AttackSpeed;
	float Range;

	std::string TexturePath;
	sf::Texture texture;
	sf::Sprite sprite;
};

i jej dziecko:

Kopiuj
#pragma once
#include "Turret.h"

class Cannon : public Turret
{
public:
	Cannon();
	Cannon(int, int);
	virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
	virtual void Attack();
	virtual float GetRange();
};

W moim obiekcie mapy mam sobie vector:

Kopiuj
std::vector<Turret*>Turrets;

Wywołuje tak:

Kopiuj
Turrets.push_back(new Cannon(2,2));

I dochodzimy tutaj do sedna sprawy kiedy próbuje coś włożyć do vectora, push_back czy emplace_back program się po prostu wysypuje. Dodam do tego to że metody Attack() czy inne nie są zaimplementowane po prostu są w pliku .cpp ale puste, tylko draw() jest zaimplentowane.
Błąd jaki mi wyrzuca visual studio:

Exception thrown: read access violation.

std::_Vector_alloc<std::_Vec_base_types<Turret *,std::allocator<Turret *> > >::_Mylast(...) returned 0x18.

edytowany 2x, ostatnio: ZbutwialyPiernik
Munvik
Może to nie będzie rozwiązanie problemu ale zrób wirtualny destruktor w klasie Turret i destruktory w klasach pochodnych.
pylaochos
Nazwy zmiennych z dużej... uhh...
06
  • Rejestracja:prawie 20 lat
  • Ostatnio:około rok
  • Postów:2440
1

Jeśli push_back powoduje wyjątek, to prawdopodobnie coś nie tak jest z samym vectorem - może go usunąłeś, uszkodziłeś lub w ogóle nie stworzyłeś.

ZP
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 2 lata
  • Postów:12
0

Zadeklarowany jest w pliku .h. A nie ma szans jego uszkodzić bo nawet się do niego nie odwołuje dopiero przy stawianiu wieżyczki

06
  • Rejestracja:prawie 20 lat
  • Ostatnio:około rok
  • Postów:2440
0

No a jak tworzysz Cannon luzem, bez dodawania do vectora, to wszystko jest ok?

ZP
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 2 lata
  • Postów:12
0

Tak wszystko jest ok, normalnie stawia mi go.

Edit. jednak nie, przy normalnym obiekcie wszystko jest ok, jeżeli robie wskaźnik na Cannon to wyskakuje mi błąd:
Exception thrown: write access violation.

this was nullptr.

edytowany 1x, ostatnio: ZbutwialyPiernik
06
  • Rejestracja:prawie 20 lat
  • Ostatnio:około rok
  • Postów:2440
0

Czyli z vectorem musi być coś nie tak. Jeśli jest polem jakiejś klasy, sprawdź, czy wszystko z tą klasą jest ok, czy nie jest gdzieś przypadkiem usuwana/nadpisywana.

ZP
Jednak to chyba jest problem z moją klasą, napisałem edit. ;/
several
  • Rejestracja:prawie 16 lat
  • Ostatnio:około 20 godzin
0

Po sf::Drawable nie dziedziczy się public?
Anyway, analogiczny kod bez SDL kompiluje się bez problemu http://melpon.org/wandbox/permlink/LqjTUC3GXYC3Mxoj


edytowany 3x, ostatnio: several
ZP
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 2 lata
  • Postów:12
0

Kod się kompiluje tylko podczas wywoływania Turrets.push_back program się wysypuje

06
Zrobiłeś dziedziczenie publiczne, jak wspomniał @several?
ZP
Zmieniłem sekunde temu i dalej to samo.
06
No to nie pozostaje Ci nic innego, jak użyć debuggera. Okno call stack może pomóc.
ZP
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 2 lata
  • Postów:12
0

Bawiłem się tym debugerem, zrobiłem wskaźnik na Cannon nie w vektorze tylko taki zwykły, no i vs mi pokazuje < Unable to read memory > i błąd.
Exception thrown: write access violation.
this was nullptr.

ZP
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 2 lata
  • Postów:12
0

Dziękuje wszystkim za pomoc błędu szukałem gdzie indziej niż był. Problem był w tym że wywoływałem push_back w obiekcie Map, tylko obiekt Map nie miał żadnej wartości był zwykłym wskaźnikiem na nic nie wskazującym. Gdyby nie zwrócenie uwagi na debuger pewnie bym tak siedział wieki na tym kodem.

06
Czyli miałem rację, że vectorem (lub obiektem, który go zawierał) jest coś nie tak.
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:2 minuty
1

polecam włączyć sobie "address sanitizer" (dostępne dla clang i gcc, nie wiem jak jest w vs).
Bardzo ładnie wykrywa większość błędów pamięci.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.