Wyciek pamięci przy tworzeniu nowego obiektu listy.

0

Witajcie.
Problem mam taki, że program ogólnie działa, ale przy użyciu odpowiednich funkcji widać, że coś jest nie tak przy tworzeniu nowych obiektów.
Tak wygląda struktura listy:

struct koleczko     
{
	unsigned int id_osoby;
	Osoba *naosobe;             
	koleczko *nastepny;
	koleczko *poprzednik;
}; 

Jest to struktura elementu w liscie dwukierunkowej. Następnie wywołując czy to konstruktor czy gdzieś dalej w kodzie taką instryukcję:

koleczko *glowa = new koleczko;

visual wskazuje wyciek pamięci. Program działa i wyniki są dobre, ale wyciek jest. Taka treść dla tej linijki:

c:\users\darek\documents\visual studio 2010\projects\przyklad\przyklad\klasa.h(46) : {131} normal block at 0x005F4978, 20 bytes long.
Data: < T J_ > 00 00 00 00 01 CD CD CD 54 FD 18 00 18 4A 5F 00
Kod sprawdziłem również na Valgrindzie i wskazał te same miejsca wycieku. Wiecie czemu new alokuje tak, że wycieka pamięć? Nie chcę pisać garbage colectora specjalnie :)

0
darekdev napisał(a)

Wiecie czemu new alokuje tak, że wycieka pamięć?

bo nie usuwasz.
jeśli decydujesz się na dynamiczną alokację za pomocą new lub malloc, to musisz gdzieś zwalniać tą pamięć. ewentualnie poczytaj o sprytnych wskaźnikach. polecam dokumentację na temat boost::scoped_ptr

0

Ale mam destruktor, mam funkcje delete w miejscach gdzie tworze tymczasowy obiekt, ale i tak zawsze w linijce z "new" pokazuje wyciek.

0
#ifndef __CHUSTECZKA_H__
#define __CHUSTECZKA_H__
//#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#include<iostream>
#include"Osoba.h"
using namespace std;
struct koleczko           //Lista będaca symulacja koleczka w zabawie
{
	unsigned int id_osoby;
	bool chusteczka;
	Osoba *naosobe;              //wskaznik na poszczegolna osobe
	koleczko *nastepny;
	koleczko *poprzednik;
};
 
class Chusteczka
{
private:
	bool czy_zabawa_trwa;
	unsigned int id_pula;
	unsigned int ilosc_uczestnikow;
	koleczko *glowa;
public:
	Chusteczka();
	~Chusteczka();
	unsigned int dolacz(Osoba* osoba);
	unsigned int dolacz(Osoba* osoba, unsigned int poz_wzg_wodzireja);
	bool rozpocznij();
	bool zakoncz();
	bool zrezygnuj(Osoba* osoba);
	bool zrezygnuj(unsigned int id_osoby);
	bool przekaz(Osoba* osoba);
	bool przekaz(unsigned int id_osoba);
	void uczestnicy();
	void uczestnicy(Osoba::Plec p);
	unsigned int ilosc() const;
};
Chusteczka::Chusteczka()
{
		czy_zabawa_trwa = false;
		id_pula = 0;
		ilosc_uczestnikow = 0;
		Osoba wodzirej(Osoba::K);
		glowa = new koleczko;
		glowa -> id_osoby = id_pula;
		glowa -> chusteczka = true;
		glowa -> nastepny = NULL;
		glowa -> poprzednik = NULL;
		glowa -> naosobe = &wodzirej;
	}
Chusteczka::~Chusteczka()
{
	koleczko *tmp;

		while(glowa)
		{
			if(glowa->nastepny==NULL) break;
			tmp = glowa->nastepny;
			delete glowa;
			glowa = tmp;
		}
		//delete tmp;
		delete glowa;
}
unsigned int Chusteczka::dolacz(Osoba* osoba)
{
	if(osoba == NULL) return 0;
	koleczko *tmp =new koleczko;
	tmp = glowa;
	while(1)
	{
		if(osoba == tmp->naosobe){ tmp=NULL;delete tmp;return 0;}
		if(tmp->nastepny==NULL) break;
		tmp = tmp -> nastepny;
	}
	this->id_pula++;
	koleczko *tmp2 = new koleczko;
	if(glowa->nastepny==NULL)
	{
		tmp2->nastepny=NULL;
		tmp2->poprzednik=glowa;
	}
	else
	{
		tmp=glowa->nastepny;
		tmp->poprzednik = tmp2;
		tmp2->nastepny=tmp;
		tmp2->poprzednik=glowa;
	}
	tmp2 -> chusteczka = false;
	tmp2 -> id_osoby = id_pula;
	tmp2 -> naosobe = osoba;
	glowa -> nastepny = tmp2;
	this->ilosc_uczestnikow++;
	tmp2=tmp=NULL;
	delete tmp2;
	delete tmp;
	return id_pula;
}
unsigned int Chusteczka::dolacz(Osoba* osoba, unsigned int poz_wzg_wodzireja)
{
	if(osoba==NULL) return 0;
	if(ilosc_uczestnikow < poz_wzg_wodzireja) return 0;
	koleczko *tmp =new koleczko;
	tmp = glowa;
	while(1)
	{
		if(osoba == tmp->naosobe){ tmp=NULL;delete tmp;return 0;}
		if(tmp->nastepny==NULL) break;
		tmp = tmp -> nastepny;
	}
	tmp = glowa;
	for( unsigned int i = 0; i < ilosc_uczestnikow-poz_wzg_wodzireja; i++) tmp = tmp ->nastepny;
	this->id_pula++;
	koleczko *tmp2 = new koleczko;
	tmp2 -> poprzednik = tmp;
	tmp2 -> nastepny = tmp -> nastepny;
	tmp2 -> chusteczka = false;
	tmp2 -> id_osoby = id_pula;
	if(tmp ->nastepny!=NULL) tmp ->nastepny->poprzednik=tmp2;
	tmp -> nastepny = tmp2;
	tmp2 -> naosobe = osoba;
	this->ilosc_uczestnikow++;
	tmp2=tmp=NULL;
	delete tmp2;
	delete tmp;
	return id_pula;
}
bool Chusteczka::rozpocznij()
{
	if(this->ilosc_uczestnikow == 0 || this->czy_zabawa_trwa) return false;
	else 
	{
		koleczko *tmp = new koleczko;
		tmp = glowa->nastepny;
		tmp->chusteczka = true;
		glowa->chusteczka = false;
		this->czy_zabawa_trwa = true;
		tmp = NULL;
		delete tmp;
		return true;
	}
}
bool Chusteczka::zakoncz()
{

	if(!this->czy_zabawa_trwa) return false;
	else
	{
		koleczko* tmp= new koleczko;
		tmp = glowa->nastepny;
		for(unsigned int i = 1; i <= ilosc_uczestnikow; i++)
		{
			if(tmp->chusteczka) tmp->chusteczka = false;
			tmp = tmp->nastepny;
		}
		glowa->chusteczka = true;
		tmp = NULL;delete tmp;
		return true;
	}
	
}
bool Chusteczka::zrezygnuj(Osoba* osoba)
{
	if(osoba == NULL) return false;
	if(this->ilosc_uczestnikow == 0) return false;
	koleczko *tmp = new koleczko;
	koleczko *lewy = new koleczko;
	koleczko *prawy = new koleczko;
	tmp = glowa ->nastepny;
	while(1)
	{

		if(osoba == tmp->naosobe && !tmp->chusteczka )
			{
				if(tmp->nastepny == NULL)
				{
					tmp -> poprzednik->nastepny=NULL;
				}
				else
				{
					lewy = tmp -> poprzednik;
					prawy = tmp -> nastepny;
					lewy -> nastepny = prawy;
					prawy -> poprzednik = lewy;
				}
				prawy=lewy=NULL;
				delete tmp;
				delete lewy;
				delete prawy;
				this->ilosc_uczestnikow--;
				return true;
			}
		if(tmp->nastepny==NULL){tmp=NULL;delete tmp; return false;}
		tmp = tmp -> nastepny;
	}

}
bool Chusteczka::zrezygnuj(unsigned int id_osoby)
{
	if(id_osoby == 0) return false;
	if(this->ilosc_uczestnikow == 0) return false;
	koleczko *tmp = new koleczko;
	koleczko *lewy = new koleczko;
	koleczko *prawy = new koleczko;
	tmp = glowa ->nastepny;
	while(1)
	{
		if(id_osoby == tmp->id_osoby && !tmp->chusteczka)
			{
				if(tmp->nastepny == NULL)
				{
					tmp -> poprzednik->nastepny=NULL; 
				}
				else
				{
					lewy = tmp -> poprzednik;
					prawy = tmp -> nastepny;
					lewy -> nastepny = prawy;
					prawy -> poprzednik = lewy;
				}
				prawy=lewy=NULL;
				delete tmp;
				delete lewy;
				delete prawy;
				this->ilosc_uczestnikow--;
				return true;
			}
		if(tmp->nastepny==NULL){ tmp=NULL;delete tmp;return false; }
		tmp = tmp -> nastepny;
	}
}
bool Chusteczka::przekaz(Osoba* osoba)
{
	if(!this->czy_zabawa_trwa) return false;
	koleczko *tmp = new koleczko;
	koleczko *tmpch = new koleczko;
	int plecc=-1;
	tmp = glowa -> nastepny;
	while(1)
	{
		if(tmp->chusteczka) {tmpch=tmp;plecc = tmp ->naosobe->plec;tmp->chusteczka=false;break;}
		if(tmp->nastepny == NULL && plecc == -1){tmp = tmpch= NULL;delete tmp;delete tmpch; return false;}
		tmp = tmp -> nastepny;
	}
	tmp = glowa -> nastepny;
	while(1)
	{	
		if(tmp->naosobe == osoba && plecc != tmp -> naosobe -> plec){tmp->chusteczka=true;tmp = tmpch= NULL;delete tmp;delete tmpch;return true;}
		else if(tmp->nastepny==NULL){tmpch->chusteczka=true;tmp = tmpch= NULL;delete tmp;delete tmpch; return false; }
		tmp = tmp -> nastepny;
	}
}
bool Chusteczka::przekaz(unsigned int id_osoba)
{
	if(id_osoba == 0) return false;
	if(!this->czy_zabawa_trwa) return false;
	koleczko *tmp = new koleczko;
	koleczko *tmpch = new koleczko;
	int plecc=-1;
	tmp = glowa -> nastepny;
	while(1)
	{
		if(tmp->chusteczka) {tmpch=tmp;plecc = tmp ->naosobe->plec;tmp->chusteczka=false;break;}
		if(tmp->nastepny == NULL && plecc == -1){tmpch->chusteczka=true;tmp = tmpch= NULL;delete tmp;delete tmpch; return false;}
		tmp = tmp -> nastepny;
	}
	tmp = glowa -> nastepny;
	while(1)
	{	
		if(tmp->id_osoby == id_osoba && plecc != tmp -> naosobe -> plec){tmp->chusteczka=true;tmp = tmpch= NULL;delete tmp;delete tmpch;return true;}
		if(tmp->nastepny==NULL){tmpch->chusteczka=true;tmp = tmpch= NULL;delete tmp;delete tmpch; return false; }
		tmp = tmp -> nastepny;
	}
}
void Chusteczka::uczestnicy()
{
	if(this->ilosc_uczestnikow==0);
	else
	{
	koleczko *tmp = new koleczko;
	tmp = glowa->nastepny;
	while(1)
	{
		cout << "plec: "<<tmp->naosobe->plec <<", nr: "<<tmp->id_osoby << endl;
		if(tmp->nastepny == NULL) break;
		tmp = tmp -> nastepny;
	}
	tmp = NULL;delete tmp;
	}
}
void Chusteczka::uczestnicy(Osoba::Plec p)
{
	if(this->ilosc_uczestnikow==0);
	else
	{
	koleczko *tmp = new koleczko;
	tmp = glowa->nastepny;
	while(1)
	{
		if(tmp->naosobe->plec == p) cout << "nr: "<<tmp->id_osoby << endl;
		if(tmp->nastepny == NULL) break;
		tmp = tmp -> nastepny;
	}
	tmp = NULL;delete tmp;
	}
}
unsigned int Chusteczka::ilosc() const
{
	return ilosc_uczestnikow;
}
#endif 
0

Wyjaśnij mi jaki sens ma gubienie wskaźnika na obiekt, przypisanie wskaźnikowi NULL-a, a następnie nałożenie na NULL-a delete ? Robisz tak w kilku miejscach. To jest zapewne jedna z przyczyn wycieków.

Poza tym igrasz z ogniem pisząc:

   
glowa -> naosobe = &wodzirej;

wodzirej jest zmienną lokalną, zatem zaraz po wyjściu ze scope zostanie zniszczona.
Popraw formatowanie kodu. Jedna instrukcja w jednej linijce. Dodatkowo strasznie zaciemniasz kod tymi wszystkimi tmp, tmp1, tmp2,..

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