Aroll605
Aroll605

Reputation: 386

Parent class destructor deletes child classes with outside initiated elements?

Spaceship.h

#include <iostream>
#include <string>
#include <math.h>
#include <vector>


class Position {

public:
    Position (std::string Name, double x, double y, double z);

private:
    std::string Name;
    double x, y, z; //Coordinates on a 3D map


};

class Flight {

public:
    Flight (Position *Start, Position *End);
    ~Flight();

private:
    Position *Start;
    Position *End;

};


class Spaceship {

public:
    Spaceship (std::string Name, Flight *flightPlan);
    ~Spaceship();

private:
    std::string Name;
    Flight *flightPlan;

};

class Universe {

public:
    Universe ();
    ~Universe ();

    void addSpaceship (Spaceship *Spaceship);

    private:
        std::vector <Spaceship*> *Spaceships; // A vector of Spaceship pointers
        std::vector <Spaceship*>::iterator start, end;
        int numberOfSpaceships;

};

Spaceship.cpp

#include "Spaceship.h"

Position::Position (std::string Name, double x, double y, double z) {
    this->Name = Name;
    this->x = x;
    this->y = y;
    this->z = z;
}


 //------------------------------------------------------------

Flight::Flight (Position *Start, Position *End) {
    this->Start = Start;
    this->End = End;
}


Flight::~Flight () {
    delete this->Start;
    delete this->End;
}



//--------------------------------------------------------------

Spaceship::Spaceship (std::string Name, Flight *flightPlan) {
    this->Name = Name;
    this->flightPlan = flightPlan;
}

Spaceship::~Spaceship () {
    delete this->flightPlan;
}

void Spaceship::printFlightPlan () {
    std::cout << "Spaceship name: " << this->Name << std::endl;
    this->flightPlan->printFlightPlan();
}

//---------------------------------------------------------------

Universe::Universe () {
    this->Spaceships = new std::vector <Spaceship*>();
    this->start = this->Spaceships->begin();
    this->end = this->Spaceships->end();

    this->numberOfSpaceships = Spaceships->size();
}

Universe::~Universe() {
    delete this->Spaceships;

}

void Universe::addSpaceship(Spaceship *Spaceship) {
    this->Spaceships->push_back(Spaceship);
    this->start = this->Spaceships->begin();
    this->end = this->Spaceships->end();
}


int main (void) {   

    Position *Start = new Position("Home", 45.566, 34.5677, -12.4565);
    Position *End = new Position ("Far Far Away", 67.4564, -56.6765, 23.4565);

    Flight *virginFlight = new Flight(Start, End);

    Spaceship *sp1 = new Spaceship("Virgin Mary", virginFlight);
    Spaceship *sp2 = new Spaceship("Something else", virginFlight);


    Universe *alpha = new Universe();

    alpha->addSpaceship(sp1);
    alpha->addSpaceship(sp2);


    delete alpha;

    return 0;
}

ALright, this should be the the cleanest version of my code. It only has constructors and destructors. If I missed some variables / functions, please assume they are there. This compiles and runs just fine. My only problem is memory leaks.

Valgrind reports allocs > deletes by a factor of 2 at least.

Upvotes: 1

Views: 85

Answers (1)

Mohamed Ali
Mohamed Ali

Reputation: 173

In deed Your program leaks. This is due to std::vector of Spaceship* in your code. an STL vector container will manage and free it's internal memory only when it contains objects not pointer to objects.

Here when you add Spaceship to your vector and did delete alpha will not release the memory pointed by sp1 and sp2 in your main program.

In modern C++ you should avoid any use of raw pointer and in stead try to use smart pointers. Here I tried to change your code and I Thought now will not leaks.

SpaceShip.h

#include <iostream>
#include <string>
#include <math.h>
#include <vector>
#include <memory>

class Position {

public:
	Position(std::string Name, double x, double y, double z);

private:
	std::string Name;
	double x, y, z; //Coordinates on a 3D map


};

class Flight {

public:
	Flight(Position *Start, Position *End);
	~Flight();
	void printFlightPlan();
private:
	Position *Start;
	Position *End;

};


class Spaceship {

public:
	Spaceship(std::string Name, Flight *flightPlan);
	~Spaceship();
	void printFlightPlan();

private:
	std::string Name;
	Flight *flightPlan;

};

class Universe {

public:
	Universe();
	~Universe();

	void addSpaceship(std::shared_ptr<Spaceship>);

private:
	std::vector <std::shared_ptr<Spaceship>> *Spaceships; // A vector of Spaceship pointers
	std::vector <std::shared_ptr<Spaceship>>::iterator start, end;
	int numberOfSpaceships;

};

#include "Spaceship.h"

Position::Position(std::string Name, double x, double y, double z) {
	this->Name = Name;
	this->x = x;
	this->y = y;
	this->z = z;
}


//------------------------------------------------------------

Flight::Flight(Position *Start, Position *End) {
	this->Start = Start;
	this->End = End;
}


Flight::~Flight() {
	/*delete this->Start;
	delete this->End;*/
}

void Flight::printFlightPlan() {
	
}


//--------------------------------------------------------------

Spaceship::Spaceship(std::string Name, Flight *flightPlan) {
	this->Name = Name;
	this->flightPlan = flightPlan;
}

Spaceship::~Spaceship() {
	delete this->flightPlan;
}

void Spaceship::printFlightPlan() {
	std::cout << "Spaceship name: " << this->Name << std::endl;
	this->flightPlan->printFlightPlan();
}

//---------------------------------------------------------------

Universe::Universe() {
	this->Spaceships = new std::vector<std::shared_ptr<Spaceship>>;
	this->start = this->Spaceships->begin();
	this->end = this->Spaceships->end();

	this->numberOfSpaceships = Spaceships->size();
}

Universe::~Universe() {
	//delete this->Spaceships;

}

void Universe::addSpaceship(std::shared_ptr<Spaceship> Spaceship) {
	this->Spaceships->push_back(Spaceship);
	this->start = this->Spaceships->begin();
	this->end = this->Spaceships->end();
}


int main(void) {

	Position *Start = new Position("Home", 45.566, 34.5677, -12.4565);
	Position *End = new Position("Far Far Away", 67.4564, -56.6765, 23.4565);

	Flight *virginFlight = new Flight(Start, End);

	std::shared_ptr<Spaceship> sp1(new Spaceship("Virgin Mary", virginFlight));
	std::shared_ptr<Spaceship> sp2(new Spaceship("Something else", virginFlight));


	Universe *alpha = new Universe();

	alpha->addSpaceship(sp1);
	alpha->addSpaceship(sp2);


	delete alpha;

	return 0;
}

Upvotes: 1

Related Questions