Dynamic memory in game

Started by
13 comments, last by rip-off 12 years, 4 months ago
Hey,
I came across an opinion that we should avoid dynamic memory in game as much as possible and what do you say?
Firstly I thought it doesn't really matter but now I have noticed an issue in my game.
I have variable in header file: bool **collision;
At certain stage in my game in source file I allocate memory to the variable like that:
collision = new bool *[size];//the size isn't constant, it differs at other stages
for(int i = 0; i < size; i++)
collision = new bool[size];

As the stage ends I remove the memory like that:
for(int i = 0; i < size; i++)
{
delete [] Collision::Obj().collision;
}
delete [] Collision::Obj().collision;

and repeating those actions some times causes the game crash eventually and I dont know if I have any memory leak or that is just becouse of dynamic memory in game?
I would be grateful for help!
Advertisement
The reasons to avoid dynamic memory is to reduce the chances of memory leaks and to simplify ownership semantics. If your code is crashing then it is because of a bug, not because you are using dynamic memory.

I would suggest not using raw arrays in C++ (especially for 2-dimensional arrays). Perhaps try something like this:

[source lang="cpp"]
collision = std::vector<std::vector<bool>>(size, false);
std::for_each(std::begin(collision), std::end(collision), [&](const std::vector<bool>& c) {
c.resize(size, false);
});
[/source]

You do not need to do anything to free memory.

I would suggest not using raw arrays in C++ (especially for 2-dimensional arrays). Perhaps try something like this:


Well, not quite:

// 1: Simple 2d array. not contiguous, simple access
vector<vector<bool>> vec( size, vector<bool>(size,false) );
vec[2][3] = true;

// 2: 2D array as contiguous 1D array, slightly more complex access
vector<bool> vec( size*size, false );
vec[size*2 + 3] = true;
A lot of this depends on your own preferences. I generally get queasy at the idea of allocating and deallocating a lot of memory on a frequent basis during runtime, so I use two strategies to avoid this. First is that I VirtualAlloc a biggish pool at startup, which I can commit from as required. The cool thing about this is that I can just call VirtualFree once and everything is deallocated for me; I don't need to track individual allocations and I'm immune to memory leaks (still need to ensure that no pointer references are used after this though). Second is that I keep a "scratch buffer" hanging around for short-lived run-time needs (generally within the scope of a single function). This is allocated one-time-only at startup, and about 2 MB is a decent enough size (your needs may be bigger or smaller). Instead of needing to make a new allocation I just set a pointer to this buffer and work away.

Of course, both of these go against the "you should not use raw arrays in C++" philosophy, but I don't fully buy into that philosophy. Other opinions may differ, but I prefer to view C++ as a toolbox and I'm not strictly dogmatic about how the language should be used.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.


I came across an opinion that we should avoid dynamic memory in game as much as possible and what do you say?
I agree completely. I believe that's more than an opinion, that's guaranteed to be a good idea. Avoiding allocations has been a good thing to do for a while. It's absolutely something to care about.
As a side note, my profiler told me a function I supposed to take very little CPU time has actually a serious performance issue... it allocates like crazy. I still have to investigate it in detail, but I expect dropping the number of allocations will improve things.


I also don't believe the "never use raw arrays" to be truth.

I don't quite understand why are you doing that... you allocate an array of pointers to bools... so you can allocate the bools later? Cannot you just put all the bools in the array in the first place? It's not like copying a bool will hammer your memory budget: only "complex" objects will need to stay unique, for others... just copy them! What are you trying to do?

Previously "Krohm"

Sorry that I reply so late and thanks for everyone who posted.
What I wanted to do was to create 2-dimension array of bools for collision so that the first index of the array would tell me about the player who got hit and second index would tell me which Player hit him:
collision[0][1] means that Player nr 0 got hit from Player nr 1.
Am I doing sth in the memory allocation wrong?
C++ doesn't provide very solid support for multi-dimensional arrays. You are generally better off using a one-dimensional array/vector and manually indexing into it, or using boost::multi_array.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Instead of allocating memory the way you do it you could as well consider allocating it contiguous in memory. This will also result in some speed up.
so instead of using your method

you could use:


collision = new bool[size*size];


and than get access with the following allocation:



col=collision[i*size+j]



which is the same as cod=collision[j]

so i would definitely consider this as well. One more good thing is that you only need to call delete[]collision ONCE.

I found it a nice thing to write a wrapper class around memory allocation. Saved me a lot of work and nerves ;-) But of course, STL vectors are proven and fast so why not use them. Just my two cents.

Peace

I open sourced my C++/iOS OpenGL 2D RPG engine :-)



See my blog: (Tutorials and GameDev)


[size=2]http://howtomakeitin....wordpress.com/

Is your original problem still a problem?

From your delete code it looks like you are calling delete outside of the class, but you create the memory inside of the class.


Collision::Obj().collision;[/quote]
This in particular looks scary. Is this a static variable in a class? The delete method is correct, but I think maybe you are giving it really bad data. Do it in two steps:

bool* delPtr = Collision::Obj().collision;
if(delPtr == NULL)
{
//breakpoint
}

See what is going on. Probably deleting it twice. Of course once deleted you have to do "collision = NULL" so that it know it points to nothing.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal


[quote name='colinhect' timestamp='1321638131' post='48]
I would suggest not using raw arrays in C++ (especially for 2-dimensional arrays). Perhaps try something like this:


Well, not quite:

// 1: Simple 2d array. not contiguous, simple access
vector<vector<bool>> vec( size, vector<bool>(size,false) );
vec[2][3] = true;

// 2: 2D array as contiguous 1D array, slightly more complex access
vector<bool> vec( size*size, false );
vec[size*2 + 3] = true;

[/quote]

... Or you could really stop reinventing the wheel, and just use boost::multi_array.

This topic is closed to new replies.

Advertisement