关于重载全局new/delete 的一些问题

重载全局new/delete的做法,网上已经可以搜到很多,不再赘述。

class A
{
public:
    A() { printf("%s, %d\n", __func__, __LINE__); }
    ~A() { printf("%s, %d\n", __func__, __LINE__); }
};

void* operator new(size_t size, const char* file, int line)
{
    void* ptr = malloc(size);
    printf("new -> %p\n", ptr);
    return ptr;
}

void* operator new[](size_t size, const char* file, int line)
{
    void* ptr = malloc(size);
    printf("new[] -> %p\n", ptr);
    return ptr;
}

void operator delete(void* ptr, const char* file, int line)
{
    printf("delete -> %p\n", ptr);
    free(ptr);
}

void operator delete[](void* ptr, const char* file, int line)
{
    printf("delete[] -> %p\n", ptr);
    free(ptr);
}

void operator delete(void* ptr)
{
    printf("delete2 -> %p\n", ptr);
    free(ptr);
}

void operator delete[](void* ptr)
{
    printf("delete2[] -> %p\n", ptr);
    free(ptr);
}

#define new new(__FILE__, __LINE__)
//#define YYDelete delete

int main(int argc, const char * argv[])
{
    A* a = new A();
    printf("a -> %p\n", a);
    delete a;
    
    char* b = new char[100];
    printf("b -> %p\n", b);
    delete[] b;
    
    A* c = new A[2];
    printf("c -> %p\n", c);
    delete[] c;
    
    A* d = new A();
    delete (void*)a;
    
    return 0;
}

运行结果:

new -> 0x100400020
A, 26
a -> 0x100400020
~A, 27
delete2 -> 0x100400020
new[] -> 0x1003057d0
b -> 0x1003057d0
delete2[] -> 0x1003057d0
new[] -> 0x100201f50
A, 26
A, 26
c -> 0x100201f58
~A, 27
~A, 27
delete2[] -> 0x100201f50
new -> 0x100300ac0
A, 26
delete2 -> 0x100300ac0

从结果来看,能看出几个问题:1. 对于基本数据类型, 如 char/short/int 等,operator new[] 内部 malloc() 结果与new 返回值是一致的。

new[] -> 0x1003057d0
b -> 0x1003057d0
delete2[] -> 0x1003057d0
2. 对于非基本数据类型,如class,operator new[] 内部 malloc() 结果与new 返回值是不一致的。
new[] -> 0x100201f50
A, 26
A, 26
c -> 0x100201f58
~A, 27
~A, 27
delete2[] -> 0x100201f50
至于这个差异,应该是由于new[], delete[] 实现原理相关,这里参考:
http://www.cnblogs.com/hazir/p/new_and_delete.html
operator new[] 内部 malloc() 返回的结果是整个memory block,包括了数组大小(32bit 机占4bytes, 64bit机占8bytes)
0x100201f58 - 0x100201f50 = 0x8
new[] 返回的地址是skip 了这个数组大小,指向对象本身。delete[] 也是相同的原理。
3. delete d; 与 delete (void*)d 并不是等价的。
delete d; --> 正常调用析构函数,并释放内存
delete (void*)d; --> 只释放内存,并没有调用析构函数
4. 下面2个delete 重载函数基本不会用到。
void operator delete(void* ptr, const char* file, int line);
void operator delete[](void* ptr, const char* file, int line);
默认只进入:
void operator delete(void* ptr);
void operator delete[](void* ptr);
具体原因还不明确,以后再补充。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值