I'm playing new operator overloading recently. I noticed a strange behavior when I overload new[] operator (the new operator for allocating arrays).
Here is my code:
#include <iostream>
using namespace std;
class Pool
{
public:
void* alloc(size_t size) {
return malloc(size);
}
};
class MyClass
{
public:
MyClass() {
cout<<"ctor called"<<endl;
}
~MyClass() {
cout<<"dtor called"<<endl;
}
void* operator new(size_t size) {
cout<<"new called, size: "<<size<<endl;
return (void*)malloc(size);
}
void* operator new[](size_t size) {
cout<<"new[] called, size: "<<size<<endl;
void* result = (void*)malloc(size);
cout<<"in new[]: "<<result<<endl;
return result;
}
void* operator new(size_t size, void* ptr) {
cout<<"new(ptr) called, size: "<<size<<endl;
return (void*)ptr;
}
void* operator new(size_t size, Pool& pool) {
cout<<"new(Pool) called, size: "<<size<<endl;
return (void*)pool.alloc(size);
}
void operator delete(void* ptr) {
cout<<"delete called, ptr: "<<ptr<<endl;
free(ptr);
}
void operator delete(void* ptr, size_t size) {
cout<<"delete called, ptr: "<<ptr<<", size: "<<size<<endl;
free(ptr);
}
void operator delete[](void* ptr) {
cout<<"delete[] called, ptr: "<<ptr<<endl;
free(ptr);
}
void operator delete[](void* ptr, size_t size) {
cout<<"delete[] called, ptr: "<<ptr<<", size: "<<size<<endl;
free(ptr);
}
uint32_t data;
};
int main() {
Pool pool;
cout<<"Pool"<<endl;
new Pool;
cout<<"MyClass"<<endl;
MyClass *ptr1, *ptr2, *ptr3;
ptr1 = new MyClass;
ptr2 = new MyClass[10]();
cout<<(void*)ptr2<<endl;
ptr3 = new(pool) MyClass;
delete ptr1;
delete[] ptr2;
delete ptr3;
return 0;
}
And the result (with gcc 64bit on OS X) is like:
Pool
MyClass
new called, size: 4
ctor called
new[] called, size: 48
in new[]: 0x7fa7f0403840
ctor called
ctor called
ctor called
ctor called
ctor called
ctor called
ctor called
ctor called
ctor called
ctor called
0x7fa7f0403848
new(Pool) called, size: 4
ctor called
dtor called
delete called, ptr: 0x7fa7f0403830
dtor called
dtor called
dtor called
dtor called
dtor called
dtor called
dtor called
dtor called
dtor called
dtor called
delete[] called, ptr: 0x7fa7f0403840
dtor called
delete called, ptr: 0x7fa7f0403870
I noticed three things: 1st, I asked to allocate 10 objects of 4 bytes in new[], but the actual request received by the function is 48 bytes. 2nd, apparently the first 8 bytes are used for other purpose: the actual address received by ptr2
is 8 bytes after the address returned by the new[] operator. 3rd, the address is also automatically translated (by going forward 8 bytes) in the overloaded delete[] function.
I also noticed that this behavior happens only when I explicitly implement the destructor. If I only use the default destructor, the 8 bytes are just gone.
Can anyone tell me what is happening behind this? What are the 8 bytes used for?
Thanks.