Zwalnianie pamięci - tablica obiektów (obiekt ma w sobie tablicę)

0

Witam,
jestem w trakcie pisania projektu, jednakże pojawił się pewien problem, którego nie mogę pokonać.

Znalazłem wyciek pamięci i zacząłem go łatać. Niestety jakimś cudem podczas usuwania tablicy obiektów program mi strasznie zwolnił (a nawet zatrzymał) w destruktorze klasy.

Bardzo proszę o rady i nakierowanie mnie, co mogę robić źle. Tak, muszą być stare i złe tablice, bo to zadanie akademickie :-)

Klasa, w której jest problem

class TabuLista {
public:
	int *sasiedzi_prawo;
	int *sasiedzi_lewo;
	int ile, b;

	TabuLista() {}

	~TabuLista(){
		delete[] sasiedzi_lewo;
		delete[] sasiedzi_prawo;
	}

	void tworzenie(int a, int i) {
		ile = a;
		b = i;
		sasiedzi_prawo = new int[ile];
		sasiedzi_lewo = new int[ile];
		for (int i = 0; i < ile; i++) {
			sasiedzi_lewo[i] = 0;
			sasiedzi_prawo[i] = 0;
		}
	}

Deklaracja tablicy tych obiektów (wszystkie będą miały w sobie po dwie tablicę int)

TabuLista *lista;
lista = new TabuLista[wielkosc];
for (int i = 0; i < wielkosc; i++) {
	lista[i].tworzenie(ile_sasiadow, i);
}

A zwalniam je następująco

	delete[] lista; //z tego, co wyczytałem to takie wywołanie powinno wywołać destruktor każdego z elementów tablicy

Co robię nie tak? Gdzie jest błąd rozumowania?

Kiedy usunę zwalnianie pamięci, wszystko bardzo ładnie się wykonuje, ale niestety - mój RAM ma skończoną pojemność :-)
Dorzuciłem do kodu kilka linijek wypisujących dane na ekran - program zatrzymuje się już przy próbie zwolnienia pierwszej tablicy (w destruktorze klasy).

Pozdrawiam serdecznie
mrozo

0

Straszny jest ten kod. Już pomijam polskie nazwy. Ale chociażby:

 delete[] sasiedzi_lewo;

A co, jeśli sasiedzi_lewo będzie NULL? Takie sprawdzenie MUSI być.

Dalej - nic nie mówiące nazwy parametrów w metodzie "tworzenie". Za kilka dni sam nie będziesz wiedział, co masz tam przekazać. Potem jeszcze przypisywanie w pętli zera. Przecież można to zrobić prościej za pomocą ZeroMemory.

No i tworzenie:

 for (int i = 0; i < wielkosc; i++) {
    lista[i].tworzenie(ile_sasiadow, i);
}

Gdzie masz zdefiniowaną zmienną "ile_sasiadow"?
Poza tym użyj debbugera. A jeszcze poza tym, użyj normalnych kontenerów z STL (vector, map, unordered_map, dequeue, czy co tam potrzebujesz). Nie będziesz się skupiał na pierdołach i bezsensownych błędach.

4

Obawiam się, że błąd może być w innym miejscu - a tu się ujawnia, jakieś wyjście poza tablicę na przykład?

1
kaczus napisał(a):

Obawiam się, że błąd może być w innym miejscu - a tu się ujawnia, jakieś wyjście poza tablicę na przykład?

Prawda, może pokaż całość, bo też jestem ciekaw.

0

Mieliście rację, znalazłem błąd - wychodzenie poza zakres

	if (pierwsza > druga) {
		lista[pierwsza].sasiedzi_prawo[wielkosc - pierwsza + druga - 1] = kadencja;
		lista[druga].sasiedzi_lewo[wielkosc - pierwsza + druga - 1] = kadencja;
	}
	else {
		lista[pierwsza].sasiedzi_prawo[pierwsza - druga - 1] = kadencja;	//powinno być [druga-pierwsza-1]
		lista[druga].sasiedzi_lewo[pierwsza - druga - 1] = kadencja;		//powinno być [druga-pierwsza-1]
	}

Może ktoś mi powiedzieć dlaczego podczas działania programu nie dostałem żadnego błędu? Program po prostu operował na adresach typu tab[-2]?

2

Owszem. Tablice w C++ nie mają żadnych zabezpieczeń przed wyjściem poza zakres. Jeśli chcesz takie mieć, to używaj metody atstd::array.

0

Dzięki wielkie za wyjaśnienie - temat do zamknięcia :-)

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