[C++] - struct z std::vector i własny destruktor


(Spwmarluk) #1

Witam,

napisałem programik, który w dużym stopniu korzysta z biblioteki vector jako pewnego rodzaju listy. Podczas kompilacji nie otrzymuję żadnych ostrzeżeń (kompiluję z -Wall). Mimo to, program 'zjada' podczas działania cały RAM i 75% swap'a, co raczej nie powinno się zdarzyć, ponieważ po każdej pętli wektory są czyszczone ( .clear() ), a obiekty stanowiące elementy wektorów niszczone, a następnie otrzymuję komunikat:

terminate called after throwing an instance of 'std::bad_alloc'

what(): std::bad_alloc

Aborted

i programik się wywala.

Moje pytanie brzmi: jak ustalić w którym dokładnie momencie występuje błąd i jak poradzić sobie z zapychaniem pamięci?

System operacyjny to SUSE 11.0


([alex]) #2

Metoda clear() nie koniecznie zwalnia pamięć.

Jeżeli przydzielasz te wektory dynamicznie to koniecznie jest zwolnienie.

Najlepiej pokaż jak to wygląda w źródłach.


(Spwmarluk) #3

Witam,

Dzięki [alex] za zmuszenie mnie do przekopania całego kodu:)

Przygotowując źródełka do wklejenia (wycinanie wszystkiego co nieistotne) nagle doznałem olśnienia można powiedzieć :smiley: Problem był oczywiście banalny, bo po prostu zapomniałem czyścić jednego z wektorów po wyjściu z pętli i tak sobie rósł w nieskończoność...

Nie ma chyba sensu zakładać nowego wątku, więc zmienię temat i przeskoczę do następnego pytania:

Czy taki destruktor ma w ogóle sens i czy usuwając obiekt takiej struktury w ogóle trzeba pisać własny destruktor?

struct element

{

	int w;

	vector wart;

	float f;

	~element();

};


element::~element()

{

	this->wart.clear();

}

Co dokładnie oznacza w tym przypadku 'przydzielanie dynamiczne pamięci'. Ja po prostu tworzę sobie wektor tak:

vector jakis_wektor;


//a potem dorzucam kolejne elementy

//petla

jakis_wektor.push_back(jakis_element);

//koniec petli


//i wywalam elementy z wektora

jakis_wektor.clear()

To oznacza, ze system sam nie zwalnia pamięci po użyciu .clear() ?


(Fiołek) #4

Ad 1: Nie ma sensu. To jest wywoływane w destruktorze std::vector.

Ad 2: Zwalnia. Dynamiczne przydzielanie pamięci to przydzielanie pamięci w trakcie działania programu. new, delete, new[], delete[], malloc, free.


([alex]) #5

Destruktor nie jest potrzebny.

Każdy vector<> ma dwie zmienne aktualna długość oraz pojemność, jeżeli dodajesz jeden element a pojemność jest większa od aktualnej długości to nie następuje przydzielanie pamięci, jeżeli zaś pojemność akurat taka sama jak długość to przedziela się pamięć z zapasem czyli kolejne kilka elementów zostaną dodane bez przydzielenia pamięci.

Metoda clear() jedynie ustawia aktualną długość na 0 ale nie koniecznie pojemność.


(Zulowski) #6

A o debuggerze i wykonywania programu ze śledzeniem krok po kroku pan słyszał?:slight_smile:


(Spwmarluk) #7

Więc tak:

Piszę w notepad++ i kompiluję przez g++.

Jest jakiś debugger do g++?

Nigdy nie korzystałem z debuggera, ale teraz widzę, że przy większych projektach przydałoby się zacząć korzystać...


(Sawyer47) #8