以下代码在堆栈上创建一个对象:
Object o;
在堆上创建对象时,我们可以使用:
Object* o;
o = new Object();
而不是:
Object* o = new Object();
当我们将堆对象创建分成两行并在第二行(o = new object()
)上调用构造函数时,这是否意味着在第一行(Object* o
)上创建了指针堆?所以Object o
将对象放在堆栈上,而Object* o
将指针放在堆栈的未来对象上?
我的第二个问题涉及两行代码是否在类之外调用。我最近读过(Global memory management in C in stack or heap?)全局变量不包含在堆栈/堆中但实际上是内存的另一部分?如果是这种情况,Object* o
会创建一个指针,它将位于内存的另一部分并指向堆对象吗?
答案 0 :(得分:85)
实际上,两个声明都没有说明堆或堆栈:
Object o;
使用自动存储创建一个对象,这意味着存储位置由声明对象的上下文决定:如果代码在函数中,则恰好是调用堆栈。但是,该行也可以是类成员,或者如您所知,在函数/类之外。
说明为何不同:
struct Foo {
Object o;
};
Foo* pf = new Foo();
现在,对象pf->o
在堆上创建,而不是在堆栈上,即使(或者更确切地说,因为)它具有自动存储。< / p>
相反,
Object* p;
只是声明一个指针,仅此而已。 指针的存储与任何其他对象无法区分:它具有自动存储功能。此外,初始化表达式对变量存储没有影响。
指针指向的是一个完全不同的问题。它可能是堆分配的对象(例如,使用new
),也可能指向另一个自动分配的对象。考虑:
Object o;
Object* p = &o;
答案 1 :(得分:10)
C ++提供了三种不同的方法来创建对象:
考虑你的情况,
Object* o;
o = new Object();
和
Object* o = new Object();
两种形式都是一样的。这意味着在堆栈上创建指针变量o(假设您的变量不属于上面的3类),它指向堆中的内存,其中包含对象。
答案 2 :(得分:4)
两种形式相同,但有一个例外:临时,当创建和赋值分开时,新(Object *)
具有未定义的值。编译器可以将它们组合在一起,因为未定义的指针不是特别有用。这与全局变量无关(除非声明是全局的,在这种情况下,对于两种形式它都是正确的。)
答案 3 :(得分:2)
A)
Object* o;
o = new Object();
`` B)
Object* o = new Object();
我认为A和B没有区别。在这两种情况下,o都是指向类Object的指针。 statement new Object()从堆内存创建一个Object类对象。赋值语句将分配的内存地址分配给指针o。
有一点我想提一下,来自堆的已分配内存大小总是sizeof(Object)而不是sizeof(Object)+ sizeof(void *)。
答案 4 :(得分:1)
在两个示例中,Object*
类型的局部变量都在堆栈上分配。如果您的程序无法检测到差异,编译器可以从两个片段中自由生成相同的代码。
全局变量的内存区域与静态变量的内存区域相同 - 它既不在堆栈上也不在堆上。您可以通过在函数内声明static
来在该区域中放置变量。这样做的结果是实例在函数的并发调用中变为 shared ,因此在使用静态时需要仔细考虑同步。
这是a link讨论正在运行的C程序的内存布局。
答案 5 :(得分:1)
C ++具有自动变量-没有堆栈变量。
自动变量表示C ++编译器自行处理内存分配/释放。 C ++可以自动处理任何类的对象-无论它是否具有动态分配的成员。通过C ++的有力保证,当执行超出声明自动变量的范围时,将自动调用对象的析构函数。在C ++对象内部,可以使用构造函数中的new
进行许多动态分配,并且当将此类对象声明为自动变量时,将执行所有动态分配,然后在析构函数中将其释放。
C中的堆栈变量无法动态分配。 C语言中的堆栈可以存储指针,固定数组或结构-全部固定大小,并且这些内容以线性顺序分配在内存中。当C程序释放堆栈变量时,它只会将堆栈指针移回原处。
即使C ++程序可以使用堆栈内存段来存储原始类型,函数的args或其他内容,但这些都是由C ++编译器而不是程序开发人员决定的。因此,从概念上讲,等于C ++自动变量和C堆栈变量是错误的。
答案 6 :(得分:0)
对象* o; o = new Object();
Object * o = new Object();
这两个语句都会在堆内存中创建对象,因为您正在使用“ new”创建对象。
要使对象创建能够在堆栈中进行,您需要遵循以下步骤:
Object o;
Object *p = &o;