最近我正在玩新運算符重載。當我重載new []操作符(分配數組的新操作符)時,我注意到了一個奇怪的行爲。運算符new []的返回地址與爲陣列得到的實際地址之間的區別
這裏是我的代碼:
#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;
}
而結果(與OS X的gcc 64位)是這樣的:
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
我注意到了三兩件事:1,我要求撥出10 new []中有4個字節的對象,但函數收到的實際請求是48個字節。第二,顯然前8個字節用於其他目的:ptr2
收到的實際地址是新的[]運算符返回的地址之後的8個字節。 3,地址也在重載的delete []函數中自動翻譯(通過前進8個字節)。
我也注意到,這種行爲只發生在我明確實現析構函數時。如果我只使用默認的析構函數,那麼這8個字節就沒了。
有誰能告訴我這背後發生了什麼?什麼是8字節用於?
謝謝。
非常感謝。仍然我很困惑,爲什麼只是添加一個析構函數會需要這樣的開銷。 –
@JimmyJi:你需要知道*有多少個*對象。 –
是的,我明白了。但是,如果我刪除析構函數聲明(僅使用由編譯器生成的缺省聲明),則只需要40個字節。額外的8個字節消失了。在這種情況下,人們將如何知道分配了多少個對象? –