[C++] Dynamic Memory Deallocation

Started by
10 comments, last by _paf 12 years, 10 months ago
Hi there!

So, consider the following code:

struct ABC
{
int *myIntArray;
};

int *myVar;


myVar = new ABC[5];


myVar.ABC[0].myIntArray = new int[5];

My question is, if it's enough just to deallocate myVar (delete [] myVar), and the memory allocated in each myIntArray is deallocated too, or if i have to deallocate every single piece of allocated memory.

Sorry if it's confusing, but i think the point of the question is understandable.


Thanks in advance.
Advertisement
Yes, you have to delete any members that are dynamically allocated. You should really be using RAII and smart pointers though. Also, use container classes so that you don't have to worry about figuring out what sizes to delete in case of pointer decay.

Also, your code doesn't make sense.myVar is an int pointer so it can't have any members.


For example, if you instead do this, you won't have to worry about manual deallocation of the member data at all.

struct ABC
{
std::vector<int> myIntArray;
};

I trust exceptions about as far as I can throw them.
Thank you for the reply.

About the code, sorry, complete mess, it's supposed to be something like this (for example):

struct VERTEX
{
float X, Y, Z;
};


struct MESH
{
unsigned int numVertices;
VERTEX *vertices;
};

struct MODEL
{
unsigned int numMesh;
MESH *meshes
};

And you'd do


MODEL myModel;
meshes = new MESH[numMesh];
meshes[0].vertices = new VERTEX[numVertices];


And that's about it (it's just an example)...

Hope it's more understandable. smile.gif
I'd recommend doing something like this instead. It's much easier and less error prone.

struct VERTEX
{
float X, Y, Z;
};

#include <vector>

struct MESH
{
std::vector<VERTEX> vertices;
};

struct MODEL
{
std::vector<MESH> meshes;
};


MODEL myModel;
myModel.meshes = std::vector<MESH>(numMesh);
myModel.meshes[0].vertices = std::vector<VERTEX>(numVertices);
I trust exceptions about as far as I can throw them.
Thank you, that is just awesome!

Sorry if it sounds weird, but it's just that i've heard about vectors before, and i always thought that it was the same as a normal array (char abc[10]), and so, it didn't fit my purpose of dynamicaly allocate memory at runtime.

Now after you show this, i went to read about vectors, and it's quite good.

However i have a question, i read that vectors use more space in memory than the one needed, in case of future reallocations, and that reallocation memory in a vector is costly in performance. But the thing is, in the above post example of a model loader, i only need to allocate memory once because it is only loaded once, and never changed again, and i've read that's possible to explicitly indicate a capacity by using vector::reserve, wich i think eliminates both problems (use extra memory, and performance cost).

But i'd like to hear your thoughts.

Thanks again...
[source lang="cpp"]
struct Mesh
{
Mesh(unsigned count) : verts(count) { }
std::vector<Vertex> verts;
};

Mesh mesh(136);
[/source]

This will create the vector with 136 elements exactly. Provided you don't push_back() any additional vertices into the vector, no further allocations will take place, so this code is functionally equivalent to your original manual approach, but with all the additional safety that has been discussed.
Thank you, that is all i needed to know! biggrin.gif

However i have a question, i read that vectors use more space in memory than the one needed, in case of future reallocations, and that reallocation memory in a vector is costly in performance.
[/quote]
Vectors tend to allocate more space than they need when used with push_back() to avoid additional reallocations. But dynamic memory allocations be be expensive. It depends, if you are reading an unknown number of vertices from a file then vector's amortised push_back() will be reasonable, then you can use the "swap to size" trick:

vector<Foo> v;

// Fill v using push_back().

// Trim to size
vector<Foo>(v).swap(v);

The latter is a little odd, but basically it creates a temporary copy of the vector (which will be the exact size required), and then swaps that into v. The over-allocated storage will be swapped into the temporary and deallocated at the end of the statement.
Well, you see i am using dynamic memory allocation (pointers), and even though i didn't know about vectors, it did the job perfectly (aside from some safety issues), because i don't need the push and pop functions of vectors.

When reading the vertices (for example), there's a line that has the exact number of vertices (somewhere in the file), so i only need to allocate memory once (the number of vertices won't change), so my problem was only that in vectors, even if i knew the exact number of vertices, the vector would allocate extra memory for future pushes or pops (in this case not needed).

Also, the performance issue of reallocation the vector isn't really a problem, due to, in this case, it would never be reallocated.

So the main problem was the extra unneeded memory.
You've got two options.

If the size is known at compile time, you can use boost::array. This is pretty much exactly like a static array except with the safety of a container class. The downside is that your class has to be templated with array size.

If the size isn't known at compile time, you'll have to use a resizeable container. But you can use encapsulation to prevent it from being resized after the initial creation.

class Mesh
{
std::vector<Vertex> verts;

public:
Mesh(size_t i): verts(i) {}

Vertex& operator [](size_t i) {return verts.at(i);}
const Vertex& operator [](size_t i) const {return verts.at(i);}
size_type size() const {return verts.size();}
};
I trust exceptions about as far as I can throw them.

This topic is closed to new replies.

Advertisement