Effective C++ 条款51:编写 new 和 delete 时需固守常规

条款51:编写 new 和 delete 时需固守常规

在编写自定义的 newdelete 操作符时,需要遵循一些常规和良好的实践。这样做不仅有助于确保内存管理的正确性,还可以提高程序的健壮性和性能。


使用场景

  1. operator new
    operator new 应该包含一个无穷循环,在尝试分配内存时,如果无法满足内存需求,它应该调用 new-handler。另外,它应能够处理 0 字节的申请,并处理错误申请(例如请求的内存大小超过了正确大小)。

  2. operator delete
    operator delete 应该在接收到空指针时不进行任何操作。对于类专属的版本,它还应该处理比正确大小更大的错误申请,确保内存的正确释放。


示例:自定义 operator newoperator delete

void* Base::operator new(std::size_t size) throw(std::bad_alloc) {
    if (size != sizeof(Base)) {
        return ::operator new(size);  // 正常的内存分配
    }
    // 在此处可以处理专门为 Base 类分配的内存
    return ::operator new(size);  // 假设是针对 Base 类的内存分配
}

void Base::operator delete(void* rawMemory, std::size_t size) throw() {
    if (rawMemory == nullptr) return;  // 空指针不处理
    
    if (size != sizeof(Base)) {
        ::operator delete(rawMemory);  // 错误大小时的处理
        return;
    }
    // 正常的内存释放
}

在这个示例中,operator newoperator delete 都进行了额外的检查和处理,确保内存分配和释放的正确性。如果请求的内存大小不符,或传递的是空指针时,程序会做出适当的响应。


注意事项

  1. 处理 0 字节申请
    operator new 应该能够处理 0 字节的内存申请,尽管分配 0 字节通常并不常见,但处理这种特殊情况能增强代码的健壮性。

  2. 内存大小检查
    当自定义 delete 时,应该检查是否请求了与实际对象大小不同的内存。如果内存大小不符,通常应调用系统的默认 delete

  3. 内存泄漏预防
    为了避免内存泄漏和未定义的行为,必须确保 delete 操作能正确处理任何类型的内存释放。特别是当内存被错误地分配或大小不一致时,要保证合适的清理。

  4. 不对空指针进行操作
    operator delete 在接收到空指针时应该直接返回,不做任何操作。这是因为删除一个空指针是合法的,并且不会导致内存错误。


总结

编写自定义的 newdelete 操作符时,遵循一些常规的做法是非常重要的。通过合理处理内存分配和释放时的特殊情况,可以避免内存泄漏、提高代码的健壮性并提升程序性能。特别是在处理大小不一致的内存、空指针和 0 字节申请时,细致的检查和相应的操作是必不可少的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值