c++ - sized operator delete[] 永远不会被调用

标签 c++ c++14 c++17

我正在尝试跟踪在我的开发中分配了多少内存。跟踪分配很容易,因为 void *operator new (size_t)void *operator new[](size_t) 的重载允许跟踪分配了多少. 使用 C++ < C++14,one can resort to a technique of over-allocating memory to store the size of the allocation

从C++14开始就有对应的void operator delete(void*p, size_t size)void operator delete[](void*p, size_t size) 这应该允许准确说明每次取消分配(不完整类型的删除除外,然后留给实现)。

但是,尽管第一个版本由 g++ 调用,其中调用删除单个对象,但我还没有找到一个编译器调用第二个版本。这是我的测试代码:

#include <iostream>
size_t currentAlloc;

void * operator new(size_t size)
{
    currentAlloc += size;
    std::cout << "1\n";
    return malloc(size);
}

void *operator new[](size_t size)
{
    std::cout << "3\n";
    currentAlloc += size;
    return malloc(size);
}

void operator delete(void *p) noexcept
{
    std::cout << "Unsized delete\n";
    free(p);
}

void operator delete(void*p, size_t size) noexcept
{
    std::cout << "Sized delete " << size << '\n';
    currentAlloc -= size;
    free(p);
}

void operator delete[](void *p) noexcept
{
    std::cout << "Unsized array delete\n";
    free(p);
}

void operator delete[](void*p, std::size_t size) noexcept
{
    std::cout << "Sized array delete " << size << '\n';
    currentAlloc -= size;
    free(p);
}

int main() {
    int *n1 = new int();
    delete n1;

    int *n2 = new int[10];
    delete[] n2;

    std::cout << "Still allocated: " << currentAlloc << std::endl;
}

使用 g++ -std=c++14 test.Cclang++ -std=c++14 test.C 编译。 g++ 的输出结果:

1
Sized delete 4
3
Unsized array delete
Still allocated: 40

我期望为第二个 delete 调用大小数组 delete 并且最后打印的值为 0 而不是 40。clang++ 不会调用任何大小的取消分配,也不会英特尔编译器。

我的代码有任何错误吗?我误解了标准吗?还是 g++ 和 clang++ 都不符合标准?

最佳答案

根据 cppreference.com ,这通常是可靠的,但未指定“删除不完整类型的对象和非类和普通可破坏类类型的数组时调用哪个版本”(我的重点)。

编译器似乎默认禁用大小删除。

关于c++ - sized operator delete[] 永远不会被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55926085/

相关文章:

c++ - 读入没有空终止符空间的数组是否合法?

c++ - 如何从delphi编译的dll调用c++中的函数

c++ - 带有 GCC 的 C++11 中的线程作用域对象

c++ - 不考虑 noexcept 规范的过载

c++ - 如何使用模板推断函数调用的大括号表达式中多维数组的大小

c++ - 求解系统(矩形全包 (RFP) 格式)

c++ - g++ 不允许在 lambda 中通过引用广义捕获 const 对象?

c++ - 编译时枚举字符串整数对

c++ - 允许 lambda/回调函数作为模板参数使用多个签名

c++ - 如果 std::string::substr 返回 std::string_view 会有什么缺点?