在C++(这不是问题)的情况下:这种类型的内存是否被分配到堆或栈上?
class Foo{
private:
int x[100];
public:
Foo();
}
我学到的东西告诉我,如果你创建了这么富的一个实例:
Foo bar = new Foo();
然后数组x分配在堆上,但是如果您创建了Foo的实例,如下所示:
Foo bar;
然后它在堆栈上创建。
我在网上找不到资源来确认这一点。
在C++(这不是问题)的情况下:这种类型的内存是否被分配到堆或栈上?
class Foo{
private:
int x[100];
public:
Foo();
}
我学到的东西告诉我,如果你创建了这么富的一个实例:
Foo bar = new Foo();
然后数组x分配在堆上,但是如果您创建了Foo的实例,如下所示:
Foo bar;
然后它在堆栈上创建。
我在网上找不到资源来确认这一点。
鉴于你例的轻微的修改:
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;
根据您的编译器和平台,实际大小可能因类/结构对齐而略有不同。
Foo类型的对象需要按顺序存储100个整数的大小。 如果您在堆栈上创建它,您将在堆栈中获取所有内容。 如果你用新的做,它会作为对象的一部分堆在堆上。
这是语言规范的一部分,我不确定你的问题是什么。
也许他在问语言规范的哪一部分说这个:-) – PolyThinker 2009-01-09 01:32:07
你的意思是
Foo* bar = new Foo();
我想。 是在堆中创建的。
是的,如果您在堆上创建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
对象是否在栈上或在堆上创建的。
严格地说,根据标准,对象不需要存在于堆栈或堆上。该标准定义了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)的存储持续时间。
对于你如何得出这个结论你有什么建议吗?我的想法和OP一样,对`new`的调用动态分配堆上的内存以获取数据。否则,像'Foo bar'这样的调用会将本地数据推送到堆栈。在任何一种情况下,我都希望类指针在堆栈中严格分配。 “public”和“private”这些修饰符如何影响分配方法? – sherrellbc 2013-11-06 00:55:47