2012-04-14 183 views
32

下面的代码创建在栈上的对象:堆栈/堆上的对象创建?

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

这两个将*大概*优化,以同样的事情,我想。 – Ryan 2012-04-14 20:33:57

+15

_pointer_始终在堆栈上创建。 – leftaroundabout 2012-04-14 20:36:41

+1

我会第二@leftaroundabout,并走得更远:在一个块中声明的所有变量都在栈上创建的;第一个示例的整个对象以及第二个对象的指针。 – 2012-04-14 20:50:39

回答

72

其实,无论声明说,大约堆或叠东西:

Object o; 

创建了自动存储意味着存储位置由对象所声明的环境确定的对象:如果代码在函数中,这恰好是调用堆栈。但是该行也可以是类成员,或者如您所知,除了函数/类之外。

为了说明为什么这是不同的:

struct Foo { 
    Object o; 
}; 

Foo* pf = new Foo(); 

现在对象pf->o创建在堆上,而不是在堆栈中,即使(或更确切地说,因为)它具有自动存储。

相反,

Object* p; 

只是声明了一个指针,仅此而已。所述指针的存储是从任何其他对象的不可区分的:它具有自动存储。此外,初始化表达式对变量存储没有影响。

什么指针所指向的是一个完全不同的事情。它可能是一个堆分配的对象(例如使用new),或者它可能指向另一个自动分配的对象。试想一下:

Object o; 
Object* p = &o; 
+1

你能解释一下“自动存储”是什么意思吗?另外,Foo pf = new Foo()会有什么区别?和Foo * pf = new Foo(); ? – user997112 2012-04-14 20:53:04

+8

Foo pf = new Foo()会有什么区别?和Foo * pf = new Foo(); - 第二个会编译,而第一个不会? – dasblinkenlight 2012-04-14 20:58:34

+0

因为我们只能使用关于堆分配的指针吗? – user997112 2012-04-14 21:04:38

3

这两种形式是相同的,只有一个例外:临时,新的(Object *)具有未定义的值,当创建和分配是分开的。编译器可能会将它们组合在一起,因为未定义的指针不是特别有用。这不涉及全局变量(除非声明是全局的,在这种情况下,对于这两种形式都是如此)。

1

在这两个示例中,Object*类型的局部变量都分配在堆栈上。如果程序没有办法检测到差异,编译器可以自由地从这两个代码片段生成相同的代码。

全局变量的内存区域与静态变量的内存区域相同 - 它既不在堆栈中,也不在堆中。您可以通过在函数中声明static来在该区域中放置变量。这样做的结果是,在您的函数的并发调用中,实例变为共享,因此在使用静态时需要仔细考虑同步。

这里是a link来讨论正在运行的C程序的内存布局。

1

A)

Object* o; 
o = new Object(); 

`` B)

Object* o = new Object(); 

我觉得A和B具有无差异。在这两种情况下,o都是指向Object类的指针。语句new Object()从堆内存中创建Object类的对象。赋值语句将分配的内存地址分配给指针o。

有一两件事我想提一提从堆中分配的内存是大小始终的sizeof(对象)不是的sizeof(对象)+的sizeof(void *的)。

6

C++提供了三种不同的方法来创建对象:

  1. 基于堆栈如临时对象
  2. 基于堆利用
  3. 静态内存分配,如全局变量和namespace-适用范围对象

考虑你的情况,

Object* o; 
o = new Object(); 

和:

Object* o = new Object(); 

这两种形式是相同的。这意味着,一个指针变量o是在堆栈上创建的(假设的变量不属于类别3以上)和其指向在堆,它包含对象的存储器。