Roel
Roel

Reputation: 3

C++ memory leak when creating an array

In my C++ game I have an array of pointers to EnemyTypes. I used Visual Leak Detector to detect memory leaks, and it's telling me I have a leak in the following piece of code:

vector<EnemyType*> enemyTypes(number_of_lines);

for (int i = 0; i < number_of_lines; i++)
{
    enemyTypes[i] = new EnemyType();
}

Let's say number_of_lines is 3 in this case. How is it possible that I'm creating a leak right here? Can I do something about it?

I started learning C++ about a month ago and I'm still learning every day, but I cannot understand some things (like this) without someone explaining me.

EDIT: I have modified the code to use a vector instead of a plain array.

Upvotes: 0

Views: 4182

Answers (4)

Roel
Roel

Reputation: 3

Turns out I was never releasing the memory (as other people told me), but Visual Leak Detector just showed me where this memory was allocated and not where the leak happened.

Upvotes: 0

rocambille
rocambille

Reputation: 15996

From your original code:

EnemyType** enemyTypes{ new EnemyType*[number_of_lines] };

for (int i = 0; i < number_of_lines; i++)
{
    enemyTypes[i] = new EnemyType();
}

When you allocate memory in C++ using new, you have to deallocate it using delete (or delete[] when you allocated an array, like your enemyTypes).

We see only part of your code, but I guess you're not doing any deallocation when you don't need the memory anymore.

By the way, you should just avoid allocating memory, or allocate it through managed pointers:

#include <vector>
#include <memory>

// ...

std::vector<std::unique_ptr<EnemyType>> enemy_types(number_of_lines);

for (auto& enemy_type : enemy_types)
{
    enemy_type = std::make_unique<EnemyType>();
}

Depending on how you use your data, you can even avoid pointers:

std::vector<EnemyType> enemy_types(number_of_lines);

Upvotes: 2

Peter
Peter

Reputation: 36637

Operator new dynamically allocates memory.

Some code, eventually, needs to release that memory using the corresponding operator delete. If your code does not do that, the memory is never released. That becomes a leak if your program loses track (e.g. the pointer used to hold the result of the new ceases to exist).

A slightly modified version of your code

int func()
{
    EnemyType** enemyTypes{ new EnemyType*[number_of_lines] };

    for (int i = 0; i < number_of_lines; i++)
    {
         enemyTypes[i] = new EnemyType();
    }
}

The pointer enemyTypes ceases to exist (since it passes out of scope) as the function returns. A consequence is that the memory created with the first usage of operator new is never released AND no pointer exists which points to it. Since that memory cannot be accessed, the results of operator new in the loop also cannot be accessed (since the only place those results are stored is in the dynamically allocated array identified by enemyTypes).

All that memory is therefore leaked at that point (the dynamically allocated memory cannot be recovered by your program, unless you use some technique outside the bounds of standard C++). Various memory checkers - if you use them - will report a leak accordingly .... either at the point where the function returns, or when the program terminates.

Upvotes: 1

Dali
Dali

Reputation: 344

When using the operator new, verify that you delete each object that you created.

A good alternative could be using smart pointers from STL or boost library. They will delete automatically your object when it became unused, thus avoiding memory leaks.

Upvotes: 0

Related Questions