[原]C++: A look at overloading new

Sometimes people use global default new operator to allocate memory for objects. But in some cases, the default new operator is not quite fit for the project / program, because allocating memory will cause the platform implementation searching for free memory bulks, merging fragments. These may be time consuming. To get good performance and control, people may need customize the new operator. Here I will talk something about overloading new operator for a specific class.

A pool based memory allocator allocates large blocks of memory and then allocates smaller objects from these blocks. When it is time to recover memory, the entire pool is deallocated at once. This usually involves returning only a few large memory blocks to the system. This greatly reduces the time consumed by memory recovery. So I will talk about something about this case.

Why to overload new?

Some may prefer to use the code like below:

MyClass *p = (MyClass*)pool->GetMem(sizeof(MyClass));
*p = MyClass();


But this kind of workaround has some issues. Recall that compiler will generate code to do the 2-step operation when newing an object: allocate memory, then call ctor on it. So naturally, problems rise:

  1. Additional memory and time are needed. Since MyClass() constructs an object of MyClass, this need extra time and space. And the temporary object only has duty for copying data to memory that p points to.
  2. Pointer dangling. Consider that when pointer or reference to another object contained by MyClass. In ctor of MyClass, some space is allocated to the pointer of the reference is initialized, and in dtor of MyClass the space is reclaimed. So after destruction of temporary object of MyClass, the pointer or reference becomes invalid. That's fatal error. Some may say, what if MyClass has operator = overloaded. Unfortunately, this is partly the truth. Yes, MyClass has operator = overloaded to perform a deep copy of the object so that no pointer dangling will occur. But,
  3. If MyClass has virtual functions, the problem rises. We all know that each object of MyClass will have a virtual table. This table is populated by compiler when constructing the object. So the code above simply copy the data to the memory, nothing of virtual table will be copied. And then you get a bulk of mud containing some data. Or even worse: the overloaded operator = itself is a virtual function.


OK, let's look at how to overload new operator in MyClass.

class MyClass
{
public:
    void* operator new(size_t, Pool*); // static function, implicitly.
    void* operator delete(void*); // static function, implicitly.
};
void* MyClass::operator new(size_t aSize, Pool* aPool)
{
    MyClass* p = (MyClass*)aPool->GetMem(aSize);
    return p; // Just return p here. Compiler will generate code to call ctor immediately after memory ready.
}


Of cause, overloading new is not as simple as demonstrated here. This is just a look at it.

Copyleft (C) 2007-2009 raof01.
请保留此权利声明,并标明文章原始地址和作者信息。

posted on 2009-04-23 16:56  raof01  阅读(162)  评论(0编辑  收藏  举报