views:

91

answers:

5

Would it be possible in C++ to create a custom allocator that works simply like this:

{
    // Limit memory to 1024 KB
    ScopedMemoryPool memoryPool(1024 * 1024); 

    // From here on all heap allocations ('new', 'malloc', ...) take memory from the pool.
    // If the pool is depleted these calls result in an exception being thrown.

    // Examples:
    std::vector<int> integers(10);
    int a * = new int [10];
}

I couldn't find something like this in the boost libraries, or anywhere else.

Is there a fundamental problem that makes this impossible?

A: 

Is there a fundamental problem that makes this impossible?

Arguing about program behavior would become fundamentally impossible. All sorts of weird issues will come up. Certain sections of the code may or may not execute though this will seeminly have no effect on the next sections which may work un-hindered. Certain sections may always fail. Dealing with the standard-library or any other third party library will become extremely difficult. There may be fragmentations at run-time at times and at times not.

dirkgently
Err.. how so? A library that cannot deal with memory allocation failures is a poor library.
Billy ONeal
Overloading global `new` and `delete` is a Bad Idea. In general. The reasons are as I described. The OP said that in case memory was not available exceptions would be thrown. Note that this does not mean that memory exhaustion in a pool for one scope necessarily affects the pool defined for the next scope.
dirkgently
+1  A: 

Yes you can make such a construct, it's used in many games, but you'll basically need to implement your own containers and call memory allocation methods of that pool that you've created.

You could also experiment with writing a custom allocator for the STL containers, although it seems that that sort of work is generally advised against. (I've done it before and it was tedious, but I don't remember any specific problems.)

Mind- writing your own memory allocator is not for the faint of heart. You could take a look at Doug Lea's malloc, which provides "memory spaces", which you could use in your scoping construct somehow.

dash-tom-bang
IMHO, that the OP wants to fine-tune allocators on a per-scope basis (probably so that he can do away with having to write different allocators and creating STL container specializations). YMMV.
dirkgently
Generally I would advise against trying to use STL containers with homegrown memory allocation routines. There are very good arguments for writing your own memory allocation systems, but they also come with a fairly high cost. (Yes, the way I see them used is to customize the allocator behavior regardless of what's hitting it, but yes there are no standard containers present and no use of `new`, `delete`, or the `malloc` family of functions.)
dash-tom-bang
@dirkgently: you're right.
StackedCrooked
A: 

I will answer a different question. Look at 'efficient c++' book. One of the things they discuss is implementing this kind of thing. That was for a web server

For this particular thing you can either mess at the c++ layer by overriding new and supplying custom allocators to the STL.

Or you can mess at the malloc level, start with a custom malloc and work from there (like dmalloc)

pm100
Do you mean this? -> http://www.amazon.com/Efficient-C-Performance-Programming-Techniques/dp/0201379503
Billy ONeal
yes (c++) by Bulka and Mayhew
pm100
+1  A: 

You would need to create a custom allocator that you pass in as a template param to vector. This custom allocator would essentially wrap the access to your pool and do whatever size validations that it wants.

Mike
A: 

If intent is that all allocations within that scope occur with that allocator object, then it's essentially a thread-local variable.

So, there will be multithreading issues if you use a static or global variable to implement it. Otherwise, not a bad workaround for the statelessness of allocators.

(Of course, you'll need to pass a second template argument eg vector< int, UseScopedPool >.)

Potatoswatter