You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义operator delete释放malloc内存的指针是否合法?GCC警告是bug吗?

这是不是GCC的bug?

我通过std::malloc分配内存,用placement new构造String类对象,同时为String声明了自定义operator delete,其内部调用std::free释放内存。已知删除非new分配的指针通常非法,但我这个场景是自定义delete适配malloc的情况,代码如下:

#include <memory>
#include <cstdlib>
#include <utility>

class String{
public:
    /*virtual*/ ~String(){}
    static void operator delete(void* p) noexcept;
};

void foo(size_t extraSize){
    if(void* mem = std::malloc(sizeof(String) + extraSize)){
        String* p = new(mem) String;
        delete p;
    }
}

// 该函数定义在其他*.cpp文件中
/*
void String::operator delete(void* p) noexcept{
    std::free(p);
}
*/

用x86-64 GCC 13.2编译后出现如下警告:

<source>: In function 'void foo(size_t)':
<source>:14:16: warning: 'static void String::operator delete(void*)' called on pointer returned from a mismatched allocation function [-Wmismatched-new-delete]
   14 |         delete p;
      |                ^
<source>:12:31: note: returned from 'void* malloc(size_t)'
   12 |     if(void* mem = std::malloc(sizeof(String) + extraSize)){
      |                    ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compiler returned: 0

执行以下任一操作可消除警告:

  • 不开启优化编译(移除-O编译选项)
  • 在当前翻译单元中定义String::operator delete(void* p)(取消注释最后几行)

结论:这不是GCC的bug

原因在于:

  1. 当自定义operator delete仅在当前翻译单元声明、未提供定义时,GCC在优化模式下无法知晓该函数的实际实现逻辑,只能依据C++默认的内存分配/释放配对规则(new对应delete,malloc对应free)进行诊断,因此触发了不匹配的警告。
  2. 当在当前翻译单元提供operator delete的定义后,编译器能明确看到函数内部调用了std::free,确认这个释放操作和malloc的分配是适配的,所以不会再触发警告。
  3. 关闭优化时,编译器的静态分析强度降低,没有执行这个配对检查,因此警告消失。

这个警告是编译器的合理诊断行为,目的是防止开发者误将常规delete用于malloc分配的内存(无自定义delete适配的场景),并非编译器bug。

内容的提问来源于stack exchange,提问作者Cooler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 22:14:58