Robin Olofsson
Robin Olofsson

Reputation: 13

Deallocate a pointer array - C++

so.. i've been struggling to deallocate an array.
I have no clue as of why there is a memoryleak but somehow there is one.
I haven't allocated any memory anywhere besides in the main function.

#include <iostream>
#include "Motorboat.h"
#include "Sailboat.h"

using namespace std;
void printSailBoats(Boat* arr[], int nrOfElements);
int main() {
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // used to check for memoryleaks in debug mode

    Boat* test[4];
    int nrOfElements = 4;

    test[0] = new Motorboat("heeelllooo",15000,"v100");
    test[1] = new Sailboat("saaailboat",1004,43.5);
    test[2] = new Motorboat("ASDK",4932,"Blabla");
    test[3] = new Sailboat("DKEOK",4992,103.4);

    printSailBoats(test,nrOfElements);

    for(int i=0; i<4; i++) {
        delete test[i];
    }

    return 0;
}

void printSailBoats(Boat* arr[], int nrOfElements) {
        // prints all sailboats
}

EDIT: Added the classes. Boat.h:

#ifndef BOAT_H
#define BOAT_H
#include <string>
using namespace std;

class Boat {
    public:
        virtual void setModel(string newModel) = 0;
        virtual void setPrice(int newPrice) = 0;
        virtual string getModel() const = 0;
        virtual int getPrice() const = 0;
        virtual string getType() const = 0;
        virtual string toString() const = 0;
};
#endif

Sailboat.h:

#ifndef SAILBOAT_H
#define SAILBOAT_H
#include "Boat.h"

class Sailboat: public Boat {
    private:
        double sailArea;
        string model;
        int price;

    public:
        Sailboat(string model, int price, double sailArea);
        void setSailArea(double newSailArea);
        double getSailArea() const;
        string toString() const;
        void setModel(string newModel);
        void setPrice(int newPrice);
        string getModel() const;
        int getPrice() const;
        string getType() const;
};
#endif

Sailboat.cpp:

#include "Sailboat.h"

Sailboat::Sailboat(string model, int price, double sailArea) {
    this->model = model;
    this->price = price;
    this->sailArea = sailArea;
}

// Setters, getters and toString...

It's pretty much the same thing for the motorboat class except that there is a string variable to store the name of the engine instead of sailarea.

Upvotes: 1

Views: 368

Answers (4)

Yamodax
Yamodax

Reputation: 431

Adding this after seeing the definitions:

class Boat {
    public:
        Boat() 
            { }
        virtual ~Boat()  // <--- this is the real catch!
                  { } 

        ...
};

Upvotes: 1

AndyG
AndyG

Reputation: 41092

The leak is here:

for(int i=0; i<4; i++) {
        delete test[i];
    }

It is deleting the elements as if they were of the same type as the base class. I.E. if you have any 'extra' information in your derived class, it will be leaked.

For example:

delete (Sailboat*)test[i]

is different than

delete (Boat*)test[i]

You need to cast test[i] to the appropriate type before deleting it. Reclaiming the type you instantiated to may be difficult, so I would recommend you simply use smart pointers instead, and not worry about the delete.

Edit: Also, virtual destructors will solve this issue. I'm still all for smart pointers ;)

Upvotes: 2

Yamodax
Yamodax

Reputation: 431

What you can do is add

#define _CRTDBG_MAP_ALLOC
#include <Crtdbg.h>

With the memory leaks output, it should give you file and line where the left over block was allocated.

Also, put a printf("Destructor of xxxx\n"); etc. in each of the destructors (Boat, Sailboat, Motoroboat). These should be called/printed on delete.

But they will only be called, if the destructor of the base calls (Baot) is marked virtual. Otherwise you'll only get Boat-destructors called (and are probably losing memory that was allocated in Sailboat and Motorboat)

Upvotes: 1

Forest Kunecke
Forest Kunecke

Reputation: 2160

It's probably a leak within your constructors. My suggestion is to make destructors for each of the classes you define to ensure that you delete any objects created in the constructor.

Upvotes: 1

Related Questions