重载新阵列运算符的安全性如何?

时间:2017-07-28 22:18:38

标签: c++ operator-overloading memory-alignment

假设我在堆上使用结构并用作

  • new []并删除[]
  • shared_ptr(new [])

然后我可以简单地重载它的新数组运算符,而不要触摸任何delete []运算符

struct  alignas(256)  MyStruct
{
    Item i1,i2;
    void * operator new[](unsigned long int size)
    {
        return aligned_alloc(256,size);
    }

    void * operator new (unsigned long int size)
    {
        return aligned_alloc(256,size);
    }
};

并认为没有任何泄漏吗?

GCC 6.3和c ++ 0x。

2 个答案:

答案 0 :(得分:5)

事实是,无法保证标准库如何实现这些operator new()函数。您的标准实现可能只需调用malloc()free(),但不需要这样做。它也可以使用sbreak()系统调用本身来支持它管理的内存对象。或者它可以使用mmap()系统调用。

这三者中的任何一个都是完全可能的,并且与其他两个实现不兼容。而且,同样糟糕的是,您的标准operator delete()实现可能会查询您传入其中的指针前面的一些隐藏数据字段以执行其内部簿记。如果指针传递到您的标准{ {1}}实际上不是匹配的operator delete()返回的指针,您有未定义的行为。事情发生的可能性非常高。

真的没办法:如果你提供operator new(),你还必须提供operator new()。否则,一切都会破裂。

答案 1 :(得分:1)

如果你对某个对象重载new,你也应该重载delete。同样,如果你重载new[],你应该重载delete[]。这是因为该对象将使用默认的delete,这可能会导致崩溃,具体取决于您与new混淆的方式。

根据您的编译器,delete可能会调用free(),但您应该养成超载newdelete的习惯,特别是如果您改变了对象被分配。