Sign in to follow this  

Memory Pool New - when to call constructor?

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

Greetings! I was wondering, how can you tell, when to call a constructor ? Just as an example: int* pIntValue = MemoryPool::new int; //no constructor CStudent* pStudent = MemoryPool::new CStudent(); //CStudent::CStudent() So how can you ever know when to run a constructor and when not?

Share this post


Link to post
Share on other sites
What are you asking? How to know when to call the constructor when you're writing the implementation for a custom memory pool?

You never call the constructor directly. You can't; it's impossible.

You can however call the placement new operator, which will call the appropriate constructor and will work in the case of fundamental types with no real constructors.

If that's not what you're asking, you'll have to clarify.

Share this post


Link to post
Share on other sites
You can call the constructor to any types at any time with placement new the same way you can call the destructor at any time. But there is no reason for that and you really shouldn't be doing it. In your code, both of the new calls are constructing the object (I think... depends on how is the memory pool operator new implemented), but since there is no reason to call an int constructor (POD types don't need construction) it may simply not.

Share this post


Link to post
Share on other sites
Quote:
Original post by Samurai Jack
Greetings!

I was wondering, how can you tell, when to call a constructor ?


Never, unless you're the person writing the C++ compiler.

Or did you mean, how to tell when a constructor will be called? Simple: primitive types (and there are only a few) don't have constructors; everything else does (although not always explicitly provided ones). But why do you care?

Share this post


Link to post
Share on other sites
The problem is I don't want to use regular "new".

The example might not be the best, it should be like this:

MemoryPool is a class with overloaded new operator. But the new does not call "new" or "malloc" instead it looks for the best spot in a huge array of bytes and assigns the pointer to that spot. That's it.

I would like to avoid this:

CStudent* pStudent = MemoryPool::myNew CStudent();
pStudent->pStudent();


The above situation should happen somehow automaticaly, there should be no regular "new" in the whole application.

Share this post


Link to post
Share on other sites
Quote:
Original post by Samurai Jack
I would like to avoid this:

CStudent* pStudent = MemoryPool::myNew CStudent();
pStudent->pStudent();

The above situation should happen somehow automaticaly, there should be no regular "new" in the whole application.


I should think you want to avoid that situation, it wouldn't compile.

A constructor is not a function, it's a constructor. It will get invoked when yu construct an object. You can't replace the language's built-in new expression, either, unless you want to write your own compiler. If you do that, you;re not dealing with C++ any more so you're on your own.

I suspect what you want to do is override ::operator new() and all its cousins (new()[], new() nothrow, new()[] nothrow, and the spouses the ::operator delete()s). Those are overrideable functions that provide an in-language way to replace memory allocations. They're also not the same as the new expression.

Most of the popular books on C++ show you how to do what you're trying to do. Try Meyers, Stroustrup, Sutter, Alexandrescu, and so on.

--smw

Share this post


Link to post
Share on other sites
Presumably you want a class that looks like this:

#include <new>
#include <cstdlib>

class ObjectFactory {
public:
template <typename T>
T * create() {
void * ptr = malloc(sizeof(T));
return new (ptr) T;
}
template <typename T, typename Arg1>
T * create(Arg1 arg1) {
void * ptr = malloc(sizeof(T));
return new (ptr) T(arg1);
}
template <typename T, typename Arg1, typename Arg2>
T * create(Arg1 arg1, Arg2 arg2) {
void * ptr = malloc(sizeof(T));
return new (ptr) T(arg1, arg2);
}

template <typename T>
void destroy(T * ptr) {
ptr->~T();
free(ptr);
}
};


Obviously replace malloc()/free() with your memory management functions.

Share this post


Link to post
Share on other sites
If you don't call new, the constructor is not called, and your object never exists, and your code crashes and dies a horrible death.

You do want to call new; you just want to decouple construction of the object from "construction" (allocation) of the storage. This is what placement new is for. Read up on it.

Share this post


Link to post
Share on other sites
is it really worth creating your own memory management unit? I've never seen any definitive specs of it. Are there any games that actualy do this? Maybe it would be part of a library that requires real-time access, and not the entire game?

I would imagine, instead of calling new inside the constructor, have your code call the memorypool::newmem in new's place... (and equivalent in the destructor) Let the compiler handle when the constructor/destructor is called, and only use the mem pool for the dynamic memory.

all the code that depends on calling the special alternative new and delete would only work with the mem pool.

for testing purposes, i could imagine just haveing the memorypool::newmem really just call new on whatvever gets passed to it (returning the pointer), and the equiv memorypool::deletemem just call delete etc. Then have some type of compiler flag that tells it to use either the default new, or the customized new when actually compiling that section of the code.

the point is, you shouldn't have to explicity call the constructor, you are doing it backwards.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ultimape
is it really worth creating your own memory management unit? I've never seen any definitive specs of it. Are there any games that actualy do this? Maybe it would be part of a library that requires real-time access, and not the entire game?

It's eminently worth it in certain situations. Using a pool-based allocator can drastically increase the speed of allocation-heavy systems while retaining the convenience of construction/destruction. I would venture to guess that the majority of commercial games do this in at least some places.

In my opinion, though, there's very little reason to write your own custom allocator. Just use boost::pool.

Share this post


Link to post
Share on other sites

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