c++ - 重载 new 返回的指针被改变

标签 c++

<分区>

我遇到了一个奇怪的问题,我创建了这个简单的程序来演示它。我知道代码本身没有多大意义,但我想强调一些我不理解的地方。

#include <iostream>
using namespace std;

class tempClass{
public:
    float n;
    tempClass(){};
    ~tempClass(){} //VERY IMPORTANT LINE
    void* operator new[](size_t size);
};


void* tempClass::operator new[](size_t size){
    tempClass* a;
    a= ::new tempClass[2];
    for (int i = 0; i < 2; i++)
    {
        a[i].n = i*10;
    }
    cout << a << endl;
    return a;
}


int main(){
    tempClass* a;
    a = new tempClass[2];
    cout << a << endl;
    cout << a[0].n << endl;
    return 0;
}

在代码中,我为我创建的类重载了 operator new。但是,函数的行为会发生变化,这取决于我是否包含类的析构函数。我注意到,如果我不包含析构函数,一切正常,而如果我这样做,指针 a 的返回值将增加 8 在一直。因此,在这个例子中,如果我包含析构函数,程序的最后一个 cout 将打印 20,如果不包含析构函数,则打印 0,在一直。为什么会这样?

最佳答案

Array-new-expressions 将未指定数量的开销传递给分配函数(即您的 operator new 重载)。这是为了允许实现记录数组元素的数量,以便在删除时调用析构函数。

如果您的实现检测到该类不需要调用析构函数(因为它是微不足道的可破坏的),它可能会选择不需要与其他方式相同的开销。

正式的写法是 8.3.4[expr.new]p11:

When a new-expression calls an allocation function and that allocation has not been extended, the new- expression passes the amount of space requested to the allocation function as the first argument of type std::size_t. That argument shall be no less than the size of the object being created; it may be greater than the size of the object being created only if the object is an array. [...]

请注意,开销未指定,因此原则上每次调用都可能不同! (这也是 placement-array-new is unusable 的原因。)但是,许多实现使用的 Itanium ABI 在“array cookie”的工作方式方面相当具体,并且符合您的经验。

关于c++ - 重载 new 返回的指针被改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45309711/

相关文章:

c++ - 指针加法

单独文件中的 C++ 内部模板类

c++ - 单例模板作为 C++ 中的基类

c++ - 在单个内核上运行的多个线程如何进行数据竞争?

c++ - 常规转换与 static_cast 与 dynamic_cast

c++ - Visual Studio 自动将括号添加到函数名称

c++ - 为什么我不能在类中初始化非常量静态成员或静态数组?

c++ - 使用Go + SWIG + C++代码清理内存管理

c++ - 如何减少 C++ map/unordered_map 容器中查找的分配?

一行中的C++可确定数组输入