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
最新推荐文章于 2023-05-20 09:00:00 发布