重载运算符new []的行为取决于析构函数

时间:2018-11-01 05:51:33

标签: c++ memory new-operator

以下代码段重载了<html> <head> </head> <body> <input type="text" name="TextBox" id="TextBox" value="0" /> <input type="Button" id='AddButton' value="+" /> <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.3.min.js"></script> </body> </html>并打印出所需的operator new[]和指针地址

size

输出

class MyClass
{
private:
    int _data;    //sizeof(MyClass) == 4

public:
    void* operator new[](size_t size)
    {
        cout << "MyClass::operator new[]" << endl;
        cout << "size = " << size << endl;
        void* p = malloc(size);
        cout << "p = " << p << endl;
        return p;
    }
};

int main()
{
    MyClass* a = new MyClass[100];
    cout << "a = " << a << endl;
}

但是,通过显式添加/定义析构函数

>>  MyClass::operator new[]
>>  size = 400
>>  p = 0x55e335a3f280
>>  a = 0x55e335a3f280

结果改变了

class MyClass
{
...
public:
    ...
    ~MyClass() {}
};

int main()
{
    MyClass* a = new MyClass[100];
    cout << "a = " << a << endl;
}

表示表达式>> MyClass::operator new[] >> size = 408 >> p = 0x564f30cd7280 >> a = 0x564f30cd7288 正在从new[]请求额外的8个字节的内存。额外的内存字节似乎正在存储数组的大小,甚至可以访问!

operator new[]

结果

cout << "info: " << *(reinterpret_cast<size_t*>(a) - 1) << endl;

我的问题是,为什么使用这8个字节的信息?这是标准的一部分吗?如果是这样,是否有解释为什么它被设计为这种方式?

2 个答案:

答案 0 :(得分:2)

调用任何数组new时是否unspecified有开销,有多少开销。此行为完全在提供给编译器的宽容范围内。多余的空间通常用于指示数组中有多少个元素。

在调用delete[]时,需要调用每个元素的析构函数。仅当我们知道有多少个元素时才能执行此操作。如果元素具有琐碎的析构函数,则无需调用它们,因此不需要空间。

请注意,尽管实现通常会委托给std::free中的operator delete,但不能保证,您也应该重载operator delete

答案 1 :(得分:1)

如果您代替析构函数添加具有非平凡析构函数的成员,例如std::string,您应该会看到类似的行为。

拥有析构函数时,运行时需要知道有多少个元素,以便可以在销毁数组之前将其销毁。

该标准未指定应如何实现这些目标,而是仅在实际数据之前存储元数据既简单,方便又高效。