Sign in to follow this  

Comment on wrapper for memory management functions

This topic is 405 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all

 

I want to have some basic control over memory allocation in my game engine. I use the classes IAllocatable and MemoryManager.

 

All classes in the engine derive from IAllocatable. Whenever objects of these classes are instantiated, they automatically call the MemoryManager which in turns calls the standard C/C++ memory functions. Does this make sense? Am I doing something wrong? Any pitfalls I should watch out for?

#ifndef IAllocatable_H
#define IAllocatable_H
 
class IAllocatable
{
public:
void* operator new(std::size_t sz);
void operator delete(void* ptr);
};
 
#endif
 


#include "IAllocatable.h"
 
void* IAllocatable::operator new( std::size_t sz )
{
return MemoryManager::malloc(sz);
}
 
void IAllocatable::operator delete( void* ptr )
{
MemoryManager::free(ptr);
}
 


#ifndef MemoryManager_H
#define MemoryManager_H
 
class MemoryManager
{
public:
void* malloc( std::size_t sz );
void free( void* ptr );
};
 
#endif
 
#include "MemoryManager.h"


void* MemoryManager::malloc( std::size_t sz )
{
return std::malloc(sz);
}
 
void MemoryManager::free( void* ptr )
{
std::free(ptr);
}

 

Share this post


Link to post
Share on other sites

Don't reinvent the wheel; there are far superior memory logging systems out there.  Is this for a learning exercise of some sort?  If not, and you're looking for a memory leak there are tools for that, Windows has the CRT memory logging systems, dmalloc should work too.  Instead using modern C++ programming practices like, naked pointers where they're best suited and smart/unique/weak pointers else where, can go a long way to make your code a lot better (when used correctly).

See Hodgman's post and the associated links here about when/how to use them:

http://www.gamedev.net/topic/683462-refering-to-unique-pointers-content/

Otherwise see:

http://dmalloc.com/

 

But seriously, every class that needs to allocate something needs to derive from your alloc class sounds like a recompiling nightmare if you make even a slight change to it.  YMMV.

Share this post


Link to post
Share on other sites

Hello all I want to have some basic control over memory allocation in my game engine. I use the classes IAllocatable and MemoryManager. All classes in the engine derive from IAllocatable.

Aside from making new wheels, how is adding a pass-through layer giving you any control that you didn't already have?

What kind of control are you looking for?

If a Foo class needs control, how do you do that?
If a Bar class needs different control, how do you do that?

I suspect that in the end it's simpler to add custom new/delete operators to those classes that need it. Edited by Alberth

Share this post


Link to post
Share on other sites

I did something like this in my engine too and added an assert into the destructor of each allocator for finding memory leaks so any unfreed memory will cause the program to stop working for debug.

 

Your approach overriding new/delete may be unfavorable because they are called implicitely, instead you should force your objects and classes to use a reference to IAllocater whenever needed. STL objects could also be allocated using custom allocater or skip them completely and make your own string, vector, array and so on ;)

 

You might find this article interesting describing the theroem of what I use even if my implementation is more different from his one

http://bitsquid.blogspot.de/2010/09/custom-memory-allocation-in-c.html

Share this post


Link to post
Share on other sites

At the very least, class MemoryManager could secure a big chunk of memory from the heap at start-up, then allocate memory from said chunk instead of going to the C++ runtime everytime. Doesn't that make sense?

 

I have access to the PhyreEngine code and they are doing something similar (can't be any more specific or post code because that stuff is proprietary).

Share this post


Link to post
Share on other sites

Allocating from a big chunk makes sense. Doing it via a shared base class, not necessarily. PhyreEngine has to co-exist with a developer's existing libraries and so a global redefinition of new/delete is far from ideal, which basically forces them to implement it that way.

 

It's also only worth doing if you have a good reason to suspect you can do things more effectively than both the user of your engine and the platform defaults. In Sony's case, they control both the engine and the platform so there's a good chance that they can write something that is tightly integrated and close to optimal. In your case, it's hard to see how you would improve over the standard new/malloc system by default, and since you don't own a platform (I assume) it makes more sense to use a 3rd party system for logging.

Share this post


Link to post
Share on other sites

Am I correct in thinking you are trying to come up with a solution to manually instrument your code to detect memory leaks? If so you might want to look at using tools like Valgrind (valgrind.org). If your code can only run on Windows then you might have luck with Dr Memory (www.drmemory.org) or IBM Purify (Hard to get hold of these days).

 

These tools can track down just leaks (in which case they are actually pretty fast) or they can be used to track down stack and heap errors too which is useful.

 

There is also a library called electric fence that you can link against and it adds canaries to malloc'ed memory so that if it is written to, it segfaults. Quite useful for heap debugging.

 

Another solution could be using boehms gc to do the allocations. This can be setup to tell you if your code would leak memory even if you are not using the actual GC functionality.

 

Other than that, smart pointers can solve most issues.

Share this post


Link to post
Share on other sites

At the very least, class MemoryManager could secure a big chunk of memory from the heap at start-up, then allocate memory from said chunk instead of going to the C++ runtime everytime. Doesn't that make sense?

So you're duplicating the functionality of the standard memory manager as well?
Likely your implementation is less good, as malloc & friends are quite old and well developed, I would assume.
 

I have access to the PhyreEngine code and they are doing something similar

There are also people using Brainfuck, does that mean you should add it too?

My point is that you should think what you want to achieve, and design for that goal. Adding stuff because "someone else did it too" doesn't generally work, as others have different, and possibly even conflicting goals with you.

So decide what you want to achieve with the memory manager, decide what you want to achieve with the big blob of memory. then design that part with the goal in mind.

If you don't know, your best option is usually not add anything until you find out what you actually need.
If you add the wrong solution now, you'll have to remove it again later, which is twice work, without gaining anything.

Share this post


Link to post
Share on other sites
Thank you for the input.
 
I am writing a game engine as a school project. One of the main objective is to design something that is extensible; efficiency is towards the bottom of the totem pole (largely immaterial but not completely irrelevant)
 
My rationale for creating the PMemoryBase class is to show that I foresaw the need for custom memory management. Does this make sense?

Share this post


Link to post
Share on other sites

I am writing a game engine as a school project. One of the main objective is to design something that is extensible
Fair enough. Unfortunately for you, extensibility in the real world has a lot more sides than they teach in class.

 

My rationale for creating the PMemoryBase class is to show that I foresaw the need for custom memory management. Does this make sense?
To me it doesn't, but I don't do your school project nor do I grade your assignment, so my considerations are fully irrelevant for your problem.

 

I think you are right that a game engine may want custom memory management. However, I would argue that C++ itself already provides the hooks that you need, at least for some forms of extensibility. (Your PMemoryBase class proves that, in fact, if C++ would not be extensible, you would not be able to do what you did with PMemoryBase class.) As such, just using C++ already gives you the extension option, you don't need to do anything for it, ie you don't even see it in the code.

 

 

Another form of extension is refactoring. We don't design everything up-front, and then simply extend the relevant classes when needed. Instead, we don't know what features will be needed, so we don't design for them. When we find new features are needed but they don't fit, we modify the code by refactoring, such that the new feature gets a proper place in the entire system.

 

 

So while all the above (and more) are valid forms of extending a program in the real world, they may not count as such in your school project. I would advice you read carefully what kind of extensions count as 'extension' in your project, and try to find a few examples of that, which gives you a good grade. (And if PMemoryBase class works for that, use it.)

Share this post


Link to post
Share on other sites

This topic is 405 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this