c++ - delete(void *, size_t) or delete(void *)

本文深入探讨了C++中overloaded delete和new操作符的使用,解释了它们的不同签名及其适用场景。重点讨论了在不同情况下选择使用void*或void*与size_t参数的原因,特别关注内存分配与释放的最佳实践。

In my previous dicuss, we have seen the example of overloaded delete and new operator. and as a matter of fact, we have seen the following signature of the delete operator. 

 

 

void operator delete(void *);
void operator delete(void *, size_t size);

 

 

As you will soon find out that they both match the same new operator

 

void operator new (size_t);

 

but which one should we  choose to use?

 

and even, you can define both the operator delete(void *) and the operator delete (void *, size_t) in the same class, and according to my test , in the placement operator overloading example, the "operator delete(void *)" has precedance over the "operator delete (void *, size_t)"....

 

so here is my rule of thme, we uses operator delete (void *, size_t size) when 

 

  • the size_t is not barely the size of the object (this could happen if the new operator has say, preallocate some space which is larger than what is required by the object itself.)
  • the size_t is necessary to determine flows or it is necessary in the clean up that the delete operator is supposed to do.
  • Booking and logging requirement.
  • This can be thought as an extension to the point 2, where you can normally see allocated memory is larger than the object itself, is when you allocate a array (new [] operator actually does this)....

 

And when to use the operator delete (void *)?

 

  • when the size of the pointer in the first parameter is exact the size of the object
  • The size_t size is irrelevant in the deallocation flow. 

 

 

 

 

 

C++中,当遇到错误信息 `error: variable has incomplete type 'void' in operator delete and new[] declaration` 时,通常意味着在声明或使用 `operator new[]` 和 `operator delete[]` 时出现了类型不完整或语法错误的问题。这种错误可能与以下几种情况有关: 1. **`operator new[]` 和 `operator delete[]` 的声明格式错误** 自定义全局或类作用域的 `operator new[]` 和 `operator delete[]` 时,必须遵循特定的函数签名规则。例如,`operator new[]` 必须返回 `void*` 类型,并接受一个 `std::size_t` 类型的参数表示要分配的内存大小;而 `operator delete[]` 则必须接受一个 `void*` 指针作为参数[^3]。如果函数签名不正确,编译器将无法识别,从而导致语法错误。 2. **未包含必要的头文件** 如果在自定义 `operator new[]` 或 `operator delete[]` 时涉及标准库组件(如 `std::size_t`),但未正确包含 `<cstddef>` 或其他相关头文件,则可能导致类型不完整的问题。例如,`std::size_t` 是定义在 `<cstddef>` 中的类型,若未包含该头文件,编译器将无法识别其完整类型,从而报错[^4]。 3. **误用 `void` 类型变量**C++ 中,`void` 类型不能被实例化,因此不能声明 `void` 类型的变量。如果在 `operator delete[]` 或 `operator new[]` 的实现中错误地声明了 `void` 类型的变量,例如 `void x;`,则会触发 `incomplete type` 错误。正确的做法是使用 `void*` 类型的指针来操作内存,而不是直接操作 `void` 类型变量[^3]。 4. **自定义内存管理函数未正确匹配标准库版本** 若在类中重载 `operator new[]` 或 `operator delete[]`,必须确保其参数列表和返回类型与标准库版本一致。例如,类作用域内的 `operator new[]` 应该声明为: ```cpp void* operator new[](std::size_t size); ``` 而对应的 `operator delete[]` 应该声明为: ```cpp void operator delete[](void* ptr) noexcept; ``` 如果声明不一致,编译器可能会报错,指出类型不完整或函数签名不匹配[^3]。 5. **`operator delete[]` 被错误地声明为非静态函数** 在类中,`operator new[]` 和 `operator delete[]` 必须被声明为静态成员函数,因为它们在对象构造之前就被调用以分配内存。如果错误地将它们声明为非静态函数,编译器将无法正确调用这些函数,导致编译错误[^3]。 ### 示例:正确声明 `operator new[]` 和 `operator delete[]` ```cpp class MyClass { public: void* operator new[](std::size_t size) { std::cout << "Custom operator new[] for size " << size << std::endl; return std::malloc(size); } void operator delete[](void* ptr) noexcept { std::cout << "Custom operator delete[]" << std::endl; std::free(ptr); } }; ``` ### 常见修复方法 - 确保 `operator new[]` 返回 `void*` 并接受 `std::size_t` 参数。 - 确保 `operator delete[]` 接受 `void*` 参数并返回 `void`。 - 在类中将 `operator new[]` 和 `operator delete[]` 声明为 `static`。 - 包含 `<cstddef>` 头文件以确保 `std::size_t` 类型完整。 - 避免在内存管理函数中声明 `void` 类型的变量。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值