Sign in to follow this  

How to separate between internal and user memory allocation?

This topic is 2076 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,

In my memory allocator manager, I have a bunch of allocate/deallocate templates like this:

[code]#ifndef _I_MEMORY_MANAGER_H
#define _I_MEMORY_MANAGER_H
#include "EngineDefs.h"
namespace JonsEngine
{
class ILogManager;
class Allocator;
class IMemoryManager
{
public:
virtual ~IMemoryManager() { }
virtual bool Init(ILogManager* logger) = 0;
virtual bool Init(Allocator_BackEnd allocatorBackEnd, ILogManager* logger) = 0;
virtual bool Destroy() = 0;
virtual bool Start() = 0;
virtual bool Stop() = 0;
virtual bool isRunning() = 0;
virtual void Tick() = 0;
template <class T>
inline T* AllocateObject() { return new (Allocate(sizeof(T))) T(); }
template <class T, class arg0>
inline T* AllocateObject(arg0 a0) { return new (Allocate(sizeof(T))) T(a0); }
template <class T, class arg0, class arg1>
inline T* AllocateObject(arg0 a0, arg1 a1) { return new (Allocate(sizeof(T))) T(a0,a1); }
template <class T, class arg0, class arg1, class arg2>
inline T* AllocateObject(arg0 a0, arg1 a1, arg2 a2) { return new (Allocate(sizeof(T))) T(a0,a1,a2); }
template <class T>
inline void DeAllocateObject(T* obj)
{
obj->~T();
DeAllocate(obj);
}
virtual void* Allocate(size_t size) = 0;
virtual void* ReAllocate(void* p, size_t n) = 0;
virtual void DeAllocate(void* obj) = 0;
virtual Allocator* GetAllocator() = 0;

};
}
#endif
[/code]

As you can see, you can either allocate/deallocate raw memory or use the allocate/deallocate templates.
However I also want to separate between engine-allocated memory and user-allcoated memorym, such as total bytes and objects allocated.I am not sure how to do it good way - the brute way is just to duplicate each allocate-method/template and add "interrnal" prefix or something, but it takes up space, looks ugly and shouldnt be part of interface.

How can I solve this in a good way?

EDIT: Added whole interface if it helps

Share this post


Link to post
Share on other sites
Define an Enum called MemoryArena and put in an entry for each major category of memory you have - engine, user, whatever else sounds good.

Then pass an instance of this enum to each allocator, using a default argument value of "user" or "unspecified" or whatever else makes sense.

Share this post


Link to post
Share on other sites
So that means I have to have two Allocators?
Also, I want to go through my IMemoryManager interface (which the previous snippet is a part of - the actuall allocate/deallocate is passed to the engine allocator,a member of the memorymanager) - so I still have to solve not having duplicate methods.
(Adding a specific Enum parameter makes it hard in the templated function dosn't it, to distinguish from T, arg0, arg1, etc)

Share this post


Link to post
Share on other sites
Wait... so you're using your [i]allocator[/i] to pass the constructor parameters to each object as you create it? I must have missed that on the first read-through of the code, sorry.

That seems really awkward. Any particular reason you are doing it this way?



Anyways, I don't see any reason why you can't do what I originally suggested, just using a template parameter instead of a function parameter.

Share this post


Link to post
Share on other sites
Is that recommended? For example, overriding it globally could possibly cause conflicts with other libraries, and you'd need a static memory allocator?
Doing it by class-by-class basis (and then with polymorphism) seems like alot of work.
That said the obvious downside to what I have now is the number of constructor arguments. Is there anything else that springs to mind?

Also - say if I would pass an enum to one of my templated functions above, how would it distinct that enum/flag for say arg0, if my function would look more like this:
[CODE]
template <class T, class arg0>
inline T* AllocateObject(arg0 a0, AllocatorMode mode = NULL) { return new (Allocate(sizeof(T)),mode) T(a0); }
[/CODE]

Share this post


Link to post
Share on other sites
It's a tradeoff, like most everything else.

For the memory mode argument - as I said, don't use a [i]function[/i] parameter. Use a [i]template [/i]parameter:

[code]template <class T, AllocationMode mode, class argT0>
T* AllocateObject(const argT0& a0) { return new (Allocate(sizeof(T), mode)) T(a0); }

// Usage:
Foo* foo = allocator.Allocate<Foo, INTERNAL_MEMORY>(fooparam);
Bar* bar = allocator.Allocate<Bar, CLIENT_MEMORY>(barparam, bazparam);
[/code]

You can also experiment with making the allocation mode parameter the last template parameter and making it default to something, although I'm not sure how various compilers would cope with that much template argument deduction going on (it should work in anything relatively modern though).

Share this post


Link to post
Share on other sites
Ok, gonna try it, thanks!

Also - is there a nice solution to include an unspecified amount of template function arguments, like variadic functions in C?
Since the problem I have is I feel restricted by the amount of arguments I can pass to my template functions, and I feel like passing a container of arguments is too much of a hassle.

Share this post


Link to post
Share on other sites
C++11 has variadic templates, but you need a conformant compiler; I don't know offhand which compilers have full variadic template support at this point. Another option is Boost which has some macro magic for generating the templates automatically.

Share this post


Link to post
Share on other sites

This topic is 2076 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