2009-01-09 19 views
4

在C++(这不是问题)的情况下:这种类型的内存是否被分配到堆或栈上?

class Foo{ 
    private: 
     int x[100]; 
    public: 
     Foo(); 
} 

我学到的东西告诉我,如果你创建了这么富的一个实例:

Foo bar = new Foo(); 

然后数组x分配在堆上,但是如果您创建了Foo的实例,如下所示:

Foo bar; 

然后它在堆栈上创建。

我在网上找不到资源来确认这一点。

回答

10

鉴于你例的轻微的修改:

class Foo{ 
    private: 
     int x[100]; 
     int *y; 
    public: 
     Foo() 
     { 
      y = new int[100]; 
     } 
     ~Foo() 
     { 
      delete[] y; 
     } 

} 

实施例1:

Foo *bar = new Foo(); 
  • x和y是在堆上:
  • 的sizeof(美孚*)被创建上堆栈。
  • 的sizeof(int)的* 100 * 2 +的sizeof(INT *)是在堆上

实施例2:

Foo bar; 
  • x是在堆栈上,和y (int)* 100在堆栈(y)上
  • sizeof(int)* 100在堆栈(y)上

根据您的编译器和平台,实际大小可能因类/结构对齐而略有不同。

+1

对于你如何得出这个结论你有什么建议吗?我的想法和OP一样,对`new`的调用动态分配堆上的内存以获取数据。否则,像'Foo bar'这样的调用会将本地数据推送到堆栈。在任何一种情况下,我都希望类指针在堆栈中严格分配。 “public”和“private”这些修饰符如何影响分配方法? – sherrellbc 2013-11-06 00:55:47

7

Foo类型的对象需要按顺序存储100个整数的大小。 如果您在堆栈上创建它,您将在堆栈中获取所有内容。 如果你用新的做,它会作为对象的一部分堆在堆上。

这是语言规范的一部分,我不确定你的问题是什么。

+0

也许他在问语言规范的哪一部分说这个:-) – PolyThinker 2009-01-09 01:32:07

1

你的意思是

Foo* bar = new Foo(); 

我想。 是在堆中创建的。

2

是的,如果您在堆上创建Foo对象,则会在堆上创建成员阵列x。当您为Foo分配动态内存时,您要求的内存长度为sizeof(Foo)(加上可能存在一些内存开销,但我们暂时忽略它),在您的示例代码中,这意味着大小为100 int s。这是类型Foo(及其内部数据)的对象的生命周期跨越范围的情况。

如果不创建堆上的Foo对象,以及Foo内部数组不是你在Foo的构造与new分配内存则该内部阵列将在堆栈上产生的指针。再次,这是为了使阵列在范围结束时自动清洁而没有任何delete。具体而言,

struct Foo { 
    int* y; 
    Foo() : y(new int()) { } 
    ~Foo() { delete y; } 
}; 

将创建在堆上y不管Foo对象是否在栈上或在堆上创建的。

10

严格地说,根据标准,对象不需要存在于堆栈或堆上。该标准定义了3种类型的存储持续时间“的,但并不完全陈述存储如何必须实现:

  1. 静态存储持续时间
  2. 自动存储持续时间
  3. 动态存储持续时间

自动存储持续时间通常(几乎总是)使用堆栈实现。

动态存储持续时间通常使用堆(最终通过malloc())实现,但即使编译器的用户也可以覆盖它。

静态存储持续时间就是它通常所说的全局变量(或静态存储)。

标准是这样说的这些事情(以下被摘录形成3.7的各个位 - 存储持续时间):

静态和自动存储持续时间 与由声明引入 对象相关联(3.1 )并且隐含地由实现(12.2)创建的 。 动态存储持续时间是 与运营商new(5.3.4)使用 创建的对象关联。

...

所有对象既不具有动态 存储时间也不是地方有 静态存储时间。这些对象的存储 将持续该程序的持续时间 (3.6.2, 3.6.3)。

...

本地对象明确宣布自动 或注册或不显式声明 static或extern具有自动 存储时间。这些对象的存储空间为 ,直到它们创建的 中的块退出。

...

对象可以执行程序(1.9)期间动态 创建,使用 新表达式(5.3.4),并使用删除表达式(5.3.5)破坏 。通过 全球分配函数 运算符new和运算符new []和 全局释放函数 运算符删除和运算符delete []提供对动态存储的访问和管理。

...

该库提供了默认的全局分配 和释放功能 定义。有些 全球分配和释放 功能是可更换(18.4.1)

最后(就在你的榜样类的数组):

3.7.4子对象的时间[基础。 stc.inherit]

成员子对象,基类子对象和数组元素的存储持续时间是其完整对象(1.8)的存储持续时间。