以下代码与 clang (x86_64-pc-linux-gnu上的版本5.0.0-3〜16.04.1)和 gcc (9.2.0 )。
void operator delete(void* ptr) noexcept {
std::cout << "overloaded delete" << std::endl;
free(ptr);
}
int main() {
int* pint = new int;
delete pint; // clang doesn't go through overloaded operator delete, gcc does
}
gcc 通过重载的operator delete
,而 clang 则避免使用{{1 }}。
(添加重载global delete
时,两个编译器都同意并通过两个重载版本)。
答案 0 :(得分:1)
允许编译器使用new
优化分配,并完全忽略对全局可替换operator new
和operator delete
的调用,即使它们有副作用,请参见{{3 }}和[expr.new]/10的C ++ 17标准草案。
如果不使用-O2
标志进行编译,则会看到同时打印了编译器和gcc主干的消息,并且忽略了启用了优化的分配。
如果编译器未删除分配/取消分配函数调用,则我认为您的operator delete
具有未定义的行为,因为您无法保证所传递的指针是由{{1}分配的},并在其上调用malloc
会导致未定义的行为。
您需要始终同时替换free
和operator new
。