std::list przechowująca obiekty a destruktory tych obiektów

0

Witam.
Mam takowy problem, próbuję przechowywać obiekty pewnej klasy w liście dwukierunkowej. niestety Elementem mojej klasy jest dynamiczna tabela, której przydzielam pamięć w konstruktorze, a zwalniam w destruktorze.
Destruktor zgodnie z oczekiwaniem wywołuje się przy instrukcji .pop_front(); Problem w tym, że wywołuje się on także przy zamykaniu programu (nawet jeśli lista jest pusta) i próbuje zwalniać już raz zwolnioną pamięć (albo zwalniać pamięć pod losowym adresem - nie jestem pewien), co powoduje błąd programu.
Fragment kodu, w którym to się dzieje:

#include "stdafx.h"
#include <iostream>
#include <list>
using namespace std;
int m;

class pakiet
{
public:
	char *d;
	pakiet(void){
		d=new char[m];
	}
	~pakiet(void){
		delete[] d;
	}
};

int main(int argc, char* argv[]){
	m=atoi(argv[2]);
	list<pakiet> lista;
	class pakiet p;
	lista.push_front(p);
	lista.pop_front();
	system("pause");
	return 0;
}

czy jest jakiś sposób na zabezpieczenie się przed ponownym wywołanie destruktora?

0

Masz zmienną lokalną 'pakiet p', która będzie niszczona zawsze przy wyjściu z main. Klasa pakiet nie posiada ani konstruktora kopiującego ani operatora przypisania, efekt jest taki, że otrzymujesz domyślne wersje, które po prostu kopiują pola - tutaj wrzucenie do listy powoduje skopiowanie wskaźnika ze zmiennej p do nowego obiektu, potem ten obiekt jest niszczony, zwalnia pamięć, następnie na wyjściu z main 'p' próbuje zwolnić już zwolnioną pamięć.

0

m=atoi(argv[2]) Tutaj program moze sie ladnie wykrzaczyc jesli nie przekazesz parametru. Powinienes sprawdza wartosc zmiennej argc. Poza tym program dziala poprawnie. A czemu destuktor wywoluje sie przy zamykaniu programu? A czemu mialby sie nie wywolywac? Likwiduje zmienna p.
Poza tym, jesli boisz sie kasowania skasowanej pamieci to dodaj dobry konstrutkor kopiujacy. Poczytaj co to jest kopia plytka i gleboka.

0
Malootki napisał(a)

m=atoi(argv[2]) Tutaj program moze sie ladnie wykrzaczyc jesli nie przekazesz parametru. Powinienes sprawdza wartosc zmiennej argc. Poza tym program dziala poprawnie.

Tak, nawet bardzo, kończy się pięknym segfaultem bądź dialogiem 'Program wykonał nieprawidłową operację...'.

0
Malootki napisał(a)

m=atoi(argv[2]) Tutaj program moze sie ladnie wykrzaczyc jesli nie przekazesz parametru. Powinienes sprawdza wartosc zmiennej argc.

To jest raczej detal do poprawienia już przy wykończaniu programu.

Świętowit napisał(a)

Masz zmienną lokalną 'pakiet p', która będzie niszczona zawsze przy wyjściu z main. Klasa pakiet nie posiada ani konstruktora kopiującego ani operatora przypisania, efekt jest taki, że otrzymujesz domyślne wersje, które po prostu kopiują pola - tutaj wrzucenie do listy powoduje skopiowanie wskaźnika ze zmiennej p do nowego obiektu, potem ten obiekt jest niszczony, zwalnia pamięć, następnie na wyjściu z main 'p' próbuje zwolnić już zwolnioną pamięć.

A to faktycznie będzie pomocne.

Dziękuje.

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