【问题标题】:value of argument for operator new[] in C++C++ 中运算符 new[] 的参数值
【发布时间】:2015-07-29 00:24:04
【问题描述】:

考虑下面的代码,它包含一个具有 newnew[] 重载的类:

#include <iostream>


class my_class  {
public:
    my_class() {};
    my_class(const my_class& rhs) {};
    ~my_class() {};

//the constructor also as applicable.
    void * operator new(size_t sz); 
    void * operator new[](size_t sz);
    void operator delete(void * ptr);
    void operator delete[](void * ptr);
private:    
};

void * my_class::operator new(size_t sz)
{
    std::cout << "at operator new, sz is: " << sz << std::endl;
}

void * my_class::operator new[](size_t sz)
{
    std::cout << "at operator new[], sz is: " << sz << std::endl;
}

void my_class::operator delete(void * ptr)
{
    std::cout << "at operator delete, ptr is: " << ptr << std::endl;
}

void my_class::operator delete[](void * ptr)
{
    std::cout << "at operator delete[], ptr is: " << ptr << std::endl;
}

int main(int argc, char ** argv)
{
    my_class * ptr = new my_class;
    my_class * arr_ptr = new my_class[1];
    return 0;
}

在终端中运行它(Cygwin)我看到了:

at operator new, sz is: 1
at operator new[], sz is: 9

为什么在调用operator new[] 时是sz == 9?谁设置的?它取决于什么(例如页面大小?)?

【问题讨论】:

  • 首先,您的new 实际上应该返回一些东西(而不是NULL)。在那之前,这有 UB。
  • 同意,这并不是一个正确的实现,只是对如何计算 size_t sz 的调查

标签: c++ operator-overloading


【解决方案1】:

一个新的-表达式,像new my_class 不仅仅调用operator newoperator new只分配内存,它的参数是它应该分配的内存大小。

operator new 的参数sz 为 1,因为这是可能的最小实例; sizeof(my_class) 是 1。

operator new[] 的参数 sz 是 9,因为这是 new[]-表达式 (new my_class[1]) 分配 1 个大小为 1 的实例的数组所需的内存量。

“额外的”8 用于跟踪诸如有多少元素之类的事情。
“额外”内存的大小取决于实现。

【讨论】:

  • 谢谢你,我改变了数组大小,我可以确认你说的是真的。
【解决方案2】:

runtime 在您调用运算符 new 时“设置”值。有一个隐含的sizeof 传递。这与调用成员函数而不隐式传递指向当前实例 this 的指针的情况相同。

在您的情况下,您有一个没有成员的类,因此理论上它的大小应该为零,但是 C++ 分配一个字节(由于对象必须至少是可寻址的事实)。这就是为什么第一次分配的结果是 1(假设你修复了你的操作符 new/new[] 来返回一些东西,在那之前你有 UB)。由于 C++ 表示动态数组的方式,第二个分配返回 9,它在某处放置了一些标头(实现定义),因此它识别出它是一个数组(因此在调用 operator delete[] 时,后者行为正常)并且可能是由于填充。

【讨论】:

  • 所以当我使用 Windows 时,会不会是 Windows 运行时决定了这一点?
  • 运行时是指在程序运行时与操作系统结合使用的标准库共享库。我不确定这是如何在内部工作的,可能所有内容都转换为一些操作系统系统调用,其中sizeof 被传递。有关运行时的一些详细信息,请参阅stackoverflow.com/questions/3900549/what-is-runtime
猜你喜欢
  • 1970-01-01
  • 2013-05-14
  • 2013-06-05
  • 1970-01-01
  • 2021-11-10
  • 2012-04-23
  • 1970-01-01
相关资源
最近更新 更多