在C ++的上下文中(并非重要):
class Foo{
private:
int x[100];
public:
Foo();
}
我学到的东西告诉我,如果你像这样创建一个Foo实例:
Foo bar = new Foo();
然后在堆上分配数组x,但是如果你创建了一个Foo实例:
Foo bar;
然后它在堆栈上创建。
我无法在线查找资源以确认这一点。
答案 0 :(得分:10)
稍微修改了你的例子:
class Foo{
private:
int x[100];
int *y;
public:
Foo()
{
y = new int[100];
}
~Foo()
{
delete[] y;
}
}
示例1:
Foo *bar = new Foo();
示例2:
Foo bar;
由于类/结构对齐,实际大小可能略有不同,具体取决于您的编译器和平台。
答案 1 :(得分:10)
严格地说,根据标准,对象不需要存在于堆栈或堆上。该标准定义了3种类型的“存储持续时间”,但没有说明存储必须如何实现:
使用堆栈通常(几乎总是)实现自动存储持续时间。
动态存储持续时间通常使用堆(最终通过malloc()
)实现,但即使编译器的用户也可以覆盖它。
静态存储持续时间通常称为全局(或静态存储)。
标准对此有所说明(以下是各种各样的3.7 - 存储持续时间的摘录):
静态和自动存储持续时间 与引入的对象相关联 通过声明(3.1)和隐含的 由实现创建(12.2)。 动态存储持续时间是 与使用的对象相关联 operator new(5.3.4)。
...
所有既没有动态的物体 储存时间也不是当地的 静态存储时间。存储 因为这些物体应该持久 计划的持续时间(3.6.2, 3.6.3)。
...
显式声明自动的本地对象 或注册或未明确声明 static或extern有自动 储存期限。存储 这些物体持续到阻挡 他们被创建退出。
...
可以动态创建对象 在程序执行期间(1.9),使用 new-expressions(5.3.4),并销毁 使用delete-expressions(5.3.5)。一个C. + +实现提供对动态存储的访问和管理 全球分配职能 operator new和operator new []和 全局释放函数 operator delete和operator delete []。
...
库提供默认值 全球分配的定义 和释放功能。一些 全球分配和解除分配 功能是可替换的(18.4.1)
最后(关于示例类中的数组):
3.7.4子对象的持续时间[basic.stc.inherit]
成员子对象,基类子对象和数组元素的存储持续时间是其完整的存储持续时间 对象(1.8)。
答案 2 :(得分:7)
Foo类型的对象按顺序存储100个整数的大小。 如果你在堆栈上创建它,你将在堆栈中获得它。 如果你用new做,它将作为对象的一部分在堆上。
这是语言规范的一部分,我不确定你的问题是什么。
答案 3 :(得分:2)
是的,如果在堆上创建x
对象,将在堆上创建成员数组Foo
。当您为Foo
分配动态内存时,您要求的内存长度为sizeof(Foo)
(可能还有一些内存开销,但暂时忽略它),在示例代码中意味着大小为100 int
秒。这个具有,可以使Foo
类型的对象(及其内部数据)的生命周期跨越范围。
如果你没有在堆上创建Foo
对象,并且Foo
的内部数组不是指向{{1}中new
分配内存的指针然后,将在堆栈上创建内部数组。同样,必须是这样的,以便在范围结束时自动清理数组而不需要任何Foo
。具体地,
delete
无论是在堆栈上还是在堆上创建struct Foo {
int* y;
Foo() : y(new int()) { }
~Foo() { delete y; }
};
对象,都会在堆上创建y
。
答案 4 :(得分:1)
你的意思是
Foo* bar = new Foo();
我想。 那个是在堆中创建的。