class test
{
public:
test(){printf("constructor/n");};
~test() {printf("destuctor/n");}
};
void main()
{
test *t = new test[12];
delete t;
}
vc6編譯,ida反編譯如下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // eax@1
int result; // eax@2
int v5; // esi@2
void *v6; // esi@5
v3 = operator new(0x10u);
if ( v3 )
{
v5 = (int)((char *)v3 + 4);
*(_DWORD *)v3 = 12; //數組長度,放在開闢空間的前四個字節
_eh_vector_constructor_iterator_((char *)v3 + 4, 1, 12, sub_401090, sub_4010B0);
//sub_401090爲構造函數,sub_4010B0爲析構
result = v5; //開闢出空間的第5個字節地址返回給test *t
}
else
{
result = 0;
}
if ( result ) //編譯優化後的delete,先判斷result是否爲空,所以很多人習慣寫的if (t!=null) delete t是沒必要的
{
v6 = (void *)(result - 4);
_eh_vector_destructor_iterator_(result, 1, *(_DWORD *)(result - 4), sub_4010B0);
result = sub_4010C0(v6); //刪除內存,內部直接調用的heapfree,沒有對free的調用
}
return result;
}
對new的調用,我們可以看到vc6確實是在爲非內置類型數據成員開闢空間的時候,多開闢了一個長度,而且長度是放在這開闢出來內存的前四個字節中,相當於調用了malloc(size+4),然後全部執行構造函數
但是delete調用就不一樣了,這裏沒有對free函數的調用,因爲他多了一個代表長度的字節,沒法用原有的庫函數了,只能從寫了一個方法
綜上,
1,delete 加不加[]對系統內置類型int double之類,沒有關係,這個情況下new delete最終是和malloc free調用同樣的代碼
2,非內置類型的情況下,delete 纔是一定加[],雖然到現在我還是不明白,爲什麼不可以學習free的方式使用__sbh_find_block等函數獲取實際大小,然後根據大小來析構,難道是以空間換時間?
所以說new必然調用malloc是可以的,delete必然調用free是不正確的,或許在不同的編譯器下面有不同的表現,歡迎高手指教
class下的new delete
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.