新总是在C++ / C# / Java中的堆上分配吗?

2022-09-03 03:25:35

我的理解一直是,无论C++、C#还是Java,当我们使用关键字创建对象时,它会在堆上分配内存。我认为这只适用于引用类型(类),并且基元类型(int,bool,float等)从不使用并且始终在堆栈上(除非它们是实例化为的类的成员变量)。但是,我一直在阅读使我怀疑这种长期存在的假设的信息,至少对于Java和C#而言。newnewnewnew

例如,我刚刚注意到在C#中,运算符可用于初始化值类型,请参阅此处。这是否是规则的例外,是语言的帮助程序,如果是这样,还会有其他哪些例外?new

有人可以澄清这一点吗?


答案 1

我认为只有引用类型(类)才需要new,而基元类型(int,bool,float等)永远不会使用new

在 C++ 中,如果需要,可以在堆上分配基元类型:

int* p = new int(42);

如果需要共享计数器(例如,在 实现中),这将非常有用。shared_ptr<T>

此外,您不会被迫在C++中的类中使用new:

void function()
{
    MyClass myObject(1, 2, 3);
}

这将在堆栈上分配。请注意,这在现代C++中很少使用。myObjectnew

此外,您可以在C++中重载(全局或特定于类),因此即使您说,该对象也不一定在堆上分配。operator newnew MyClass


答案 2

我对Java并不确切了解(而且似乎很难获得有关它的文档)。

在 C# 中,调用构造函数并返回一个新对象。如果它是值类型,则将其分配在堆栈(例如局部变量)或堆上(例如,盒装对象,引用类型对象的成员)。如果它是引用类型,则它始终位于堆上,并由垃圾回收器管理。有关详细信息,请参阅 http://msdn.microsoft.com/en-us/library/fa0ab757(v=vs.80).aspxnew

在C++中,“new 表达式”返回一个指向具有动态存储持续时间(即您必须销毁自己)的对象的指针。在C++标准中没有提到堆(具有这种含义),并且通过该机制获得此类对象是实现定义的。