run time error while destroying a vector

The following code means to destroy a vector defined with unique_ptr to objects.
Oddly enough it works smoothly on the computer of a friend, but abends on mine.
To be precise, with a vector pointing to three objects, the first iteration works, poping back the last pointer, and the program abends with the second pop_back.

Any idea ?

Many thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Destructeur
Systeme::~Systeme() {
	
	supprime();
	
}

void Systeme::supprime(){
	
	while (!Is_collec_part.empty()){
		
		Is_collec_part.pop_back();
		}
	
}
Last edited on
you may simply use the default destructor, and to clear a vector you could call the .clear() method.
apart from that there isn't something clearly wrong in the 15 lines that you posted.
I'm still having the same problem with destruction. The program uses 3 classes.
A virtual class Particule
A sub class TxtNeon
A class Systeme wich contains a vector, named Is_collec_part, with unique_ptr pointing to Particule.

The main program does the following :
- creates two Particule-Neon objects
- adds unique_pointers to them in the Is_collec_part vector
- displays the objects
- destroys the two Particule-Neon objects
- calls a function named Supprime from the Systeme destructor
in wich there is a loop to pop_back the unique-pointers. First pop_back works, second abends.

NB: using clear abends as well.

1) Is it normal to have the objects destroyed before the unique pointers ?
2) What is wrong ?

Many thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
//FILE testSysteme.cc ===============

using namespace std;

int main()
{	Systeme systeme(2,4,5);
	
	Vecteur p(1,2,3);
	Vecteur q(4,5,6);
	TxTNeon a( p, q, 4.002602);
	cout<<"a en t0 "<<a<<endl;

	Vecteur p2(2,2,3);
	Vecteur q2(4,5,6);
	TxTNeon b( p2, q2, 4.002602);
	cout<<"b en t0 "<<b<<endl;
	cout<<endl;
	
	a.evolue(1);
	cout<<"a en t1 "<<a<<endl;
	b.evolue(1);
	cout<<"b en t1 "<<b<<endl;
	cout<<endl;
	
	a.dessine();
	cout<<endl;


	systeme.ajoute(a);
	systeme.ajoute(b);
	systeme.dessine();
	cout<<endl;
	
	return 0;
	
}
//FILE Systeme.h 
============

class Systeme: public Dessinable {
	
	public:
	
	Systeme();										//Constructeur par défaut
	Systeme(double hauteur,double largeur,double profondeur);//Constructeur

	~Systeme();										//Destructeur
	void supprime();

//Méthodes publiques de la classe	
	void ajoute(Particule& b);		//Ajoute une particule dans Is_collec_part
	void evolue(double dt);			//Fait avancer le systeme d'un pas de temps(mouvement, rebonds, collisions)
	
//Polymorphisme hérité de Dessinable
	void dessine();					// METHODE A REVOIR QUAND ON SAURA CE QU'ON VEUT
		
	protected:
	
	vector<unique_ptr<Particule>> Is_collec_part; //vecteur de ptr uniques vers les particules
	Enceinte enceinte;
	Systeme(Systeme const& b)=delete;	//constructeur de copie interdit
	bool Is_dessinable;	
	
//Methodes privées de la classe
	
	Systeme operator=(Systeme const& a)=delete;
	
	
};

#endif

//FILE Systeme.cc 
=============
//Constructeurs
Systeme::Systeme(){
	
	Enceinte();			// appel au constructeur par défaut de la classe enceinte
	
	for(size_t i(0); i<Is_collec_part.size(); i++){
		
		Is_collec_part[i]=nullptr;
		
	}

	Is_dessinable=false;
}

Systeme::Systeme(double hauteur, double largeur, double profondeur){
	
	Enceinte(hauteur, largeur, profondeur);// constructeur d'enceinte
	
	for(size_t i(0); i<Is_collec_part.size(); i++){
		
		Is_collec_part[i]=nullptr;
		
	}

	Is_dessinable=false;
}

//Destructeur
Systeme::~Systeme() {
		
	supprime();
	
}

void Systeme::supprime(){
	
	cout<<"destruction systeme"<<endl;
	int	s=Is_collec_part.size();
	cout<<"Destruction systeme. Size : "<<s<<" particules."<<endl;
	
	while (!Is_collec_part.empty()){
		int	s=Is_collec_part.size();
		cout<<"Size : "<<s<<endl;		
		Is_collec_part.pop_back();
		cout<<"Next : "<<endl;				
		}
}
	
	
//Méthodes publiques de la classe	
void Systeme::ajoute(Particule& b){
 
	unique_ptr<Particule> p1(&b);
	Is_collec_part.push_back(move(p1));

}

void Systeme::evolue(double dt){
	
	for(size_t i(0); i<Is_collec_part.size(); i++){
		
		Is_collec_part[i]->evolue(dt);
		
	}
	
}

//Polymorphisme hérité de Dessinable

void Systeme::dessine(){
	
	int s;
	int i;

	cout<<"dessine systeme "<<endl;
	s=Is_collec_part.size();
	cout<<"Size : "<<s<<endl;
	for (i=0; i<s; i++) {
		cout<<*Is_collec_part[i]<<endl;
		}
}

//FILE Particule.h 
============
#ifndef PRJ_PARTICULE_H
#define PRJ_PARTICULE_H
#include <iostream>
#include <cmath>	
#include "Vecteur.h"
#include "Dessinable.h"

using namespace std;


class Particule : public Dessinable {
	public:

//Constructeurs-Destructeur
	Particule();							//Constructeur par défaut (0, 0, 0)
	Particule(Vecteur position, Vecteur vitesse, double masse);//Constructeur
	Particule(const Particule& Old_Particule);//Constructeur de copie
	
	~Particule(){	cout<<"destruction particule"<<endl;};							//Destructeur	
	
//Méthodes publiques de la classe	
	Vecteur getposition() const;			//Lecture et mise à jour des données privées
	void setposition(Vecteur v);
	Vecteur getvitesse() const;
	void setvitesse(Vecteur v);
	double getmasse() const;
	void setmasse(double d);
	void evolue(double dt);					//Déplace la particule mvt rectiligne uniforme
	void affiche(ostream& sortie) const;	// Méthode remplacée par une surcharge d'opérateur


											//Méthodes virtuelles
	virtual void dessine()=0;				


	protected:
	
	Vecteur Is_position;
	Vecteur Is_vitesse;
	double Is_masse;
	bool Is_dessinable;						// PROPRIETE A REVOIR QUAND ON SAURA CE QU'ON VEUT
	
};

ostream& operator<<( ostream& sortie, const Particule& p);  //Surcharge de l'affichage
#endif // PRJ_PARTICULE_H
//FILE Particule.cc =======================================================
#include "Particule.h"
#include "TxTNeon.h"

//Constructeurs
Particule::Particule(){
	
	Is_position.setx(0);
	Is_position.sety(0);
	Is_position.setz(0);
	
	Is_vitesse.setx(0);
	Is_vitesse.sety(0);
	Is_vitesse.setz(0);
	
	Is_masse=0;
	
	Is_dessinable=false;
	
}

Particule::Particule(Vecteur position, Vecteur vitesse, double masse){
	
	Is_position.setx(position.getx());
	Is_position.sety(position.gety());
	Is_position.setz(position.getz());
	
	Is_vitesse.setx(vitesse.getx());
	Is_vitesse.sety(vitesse.gety());
	Is_vitesse.setz(vitesse.getz());
	
	Is_masse=masse;

	Is_dessinable=false;
	
}

Particule::Particule(const Particule& Old_Particule){

	Is_position=Old_Particule.getposition();
	Is_vitesse=Old_Particule.getvitesse();
	Is_masse=Old_Particule.getmasse();
	
	Is_dessinable=false;
	
}
	
//Méthodes publiques de la classe	
//Get et set position, vitesse, masse
 Vecteur Particule::getposition() const{
	return Is_position;
}

void Particule::setposition(Vecteur v){

	Is_position.setx(v.getx());
	Is_position.sety(v.gety());
	Is_position.setz(v.getz());
}
	
Vecteur Particule::getvitesse() const{
	return Is_vitesse;
}

void Particule::setvitesse(Vecteur v){

	Is_vitesse.setx(v.getx());
	Is_vitesse.sety(v.gety());
	Is_vitesse.setz(v.getz());
}
	
double Particule::getmasse() const{
	return Is_masse;
}

void Particule::setmasse(double d){
	Is_masse=d;
}

//Déplace la particule mvt rectiligne uniforme
void Particule::evolue(double dt){
	
	Is_position.setx( Is_position.getx() + Is_vitesse.getx()*dt);
	Is_position.sety( Is_position.gety() + Is_vitesse.gety()*dt);
	Is_position.setz( Is_position.getz() + Is_vitesse.getz()*dt);
	
}
		 
// Méthodes remplacées par des surcharges d'opérateurs extérieures à la classe
//Affichage
void Particule::affiche(ostream& sortie) const{

		    sortie<<"position: "<<Is_position.getx()<<" "<<Is_position.gety()<<" ";
		    sortie<<Is_position.getz()<<"  "<<"vitesse: "<<Is_vitesse.getx()<<" ";
		    sortie<<Is_vitesse.gety()<<" "<<Is_vitesse.getz();
		    sortie<<"  "<<"masse: "<<Is_masse;
		    
		     }
			     
// Méthode extérieure à la classe		 
ostream& operator<<( ostream& sortie,const Particule& p){

			 p.affiche(sortie);
			 return sortie;
			 }		
//FILE TxtNeon.h =======================================================
#ifndef PRJ_TXTNEON_H
#define PRJ_TXTNEON_H
#include "Particule.h"
#include <iostream>
#include <cmath>

using namespace std;

class TxTNeon:public Particule{
	public:
	
	TxTNeon();														//constructeur par defaut (0,0,0)
	TxTNeon(Vecteur vitesse, Vecteur position, double masse);		//constructeur 
	
	~TxTNeon(){	cout<<"destruction neon"<<endl;};													//destructeur
	
//Polymorphisme
	void dessine();							// METHODE A REVOIR QUAND ON SAURA CE QU'ON VEUT

	
};

#endif	 
//FILE TxtNeon.cc =======================================================
#include "TxTNeon.h"

//Constructeurs
TxTNeon::TxTNeon():Particule(){
		
	}
	
TxTNeon::TxTNeon(Vecteur vitesse, Vecteur position, double masse):
	Particule (vitesse, position, masse){

	}

//Polymorphisme
void TxTNeon::dessine() {

	cout<<"Neon "<<*this<<endl;
		    
    }
> What is wrong ?

class Particule : public Dessinable

Is the destructor of Dessinable virtual? If not, make it virtual.
Thank you,

But the destructor of Dessinable is virtual.
I still have the abend.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef PRJ_DESSINABLE_H
#define PRJ_DESSINABLE_H

using namespace std;

class Dessinable {
	public:
		Dessinable(){};				//Constructeur
		virtual ~Dessinable(){};	//Destructeur
		virtual void dessine()=0;	//Methode publique
	
};
#endif // PRJ_DESSINABLE_H
Last edited on
Neither a, nor b in main are allocated with new, so why are you feeding them to std::unique_ptr via Systeme::ajoute with the default deleter (which assumes they were allocated by new?)
Thank you,

I made the change you suggested.

As well, I move to another environment (Linux). I still have the error, but it gives a message now : invalid pointer.
This happens in member supprime with the pop_back instruction.

Thanks for your help.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <cmath>	
#include "Vecteur.h"
#include "Particule.h"
#include "Enceinte.h"
#include "Dessinable.h"
#include "Systeme.h"
#include "TxTNeon.h"
#include <vector>
#include <memory>

using namespace std;

int main()
{	Systeme systeme(2,4,5);
	
	TxTNeon a;
	TxTNeon b;
	
	Vecteur p(1,2,3);
	Vecteur q(4,5,6);
	//TxTNeon a( p, q, 4.002602);
	a = *new TxTNeon (p, q, 4.002602);
	cout<<"a en t0 "<<a<<endl;

	Vecteur p2(2,2,3);
	Vecteur q2(4,5,6);
	//TxTNeon b( p2, q2, 4.002602);
	b = *new TxTNeon (p2 , q2, 4.002602);
	cout<<"b en t0 "<<b<<endl;
	
	//TxTNeon c(Vecteur (0,1,2), Vecteur (3,4,5), 6);
	//cout<<c<<endl;

	a.evolue(1);
	cout<<"a en t1 "<<a<<endl;
	b.evolue(1);
	cout<<"b en t1 "<<b<<endl;
	
	a.dessine();


	systeme.ajoute(a);
	systeme.ajoute(b);
	//systeme.ajoute(c);
	systeme.dessine();
	
	systeme.supprime();
	
	return 0;
	
}
Topic archived. No new replies allowed.