在C++的背景下(这并不重要):
class Foo{
private:
int x[100];
public:
Foo();
}
我了解到,如果你像这样创建Foo的实例:
Foo bar = new Foo();
那么数组x将在堆上分配,但是如果你像这样创建Foo实例:
Foo bar;
然后它被创建在堆栈上。
我找不到在线资源来确认这一点。
在C++的背景下(这并不重要):
class Foo{
private:
int x[100];
public:
Foo();
}
我了解到,如果你像这样创建Foo的实例:
Foo bar = new Foo();
那么数组x将在堆上分配,但是如果你像这样创建Foo实例:
Foo bar;
然后它被创建在堆栈上。
我找不到在线资源来确认这一点。
全局分配和释放函数的定义。一些全局分配和释放函数是可替换的(18.4.1)。静态存储期和自动存储期与引入声明(3.1)或由实现隐含创建(12.2)的对象相关联。动态存储期与使用new运算符(5.3.4)创建的对象相关联。
...
既没有动态存储期也不是本地对象的所有对象都具有静态存储期。这些对象的存储期将持续整个程序的执行时间(3.6.2、3.6.3)。
...
明确声明为自动或寄存器,或未明确声明为静态或外部的本地对象具有自动存储期。这些对象的存储期将持续到它们被创建的块退出。
...
可以在程序执行过程中使用new表达式(5.3.4)动态创建对象,并使用delete表达式(5.3.5)销毁对象。C++实现通过全局分配函数operator new和operator new[]以及全局释放函数operator delete和operator delete[]提供对动态存储的访问和管理。
...
标准库提供了默认的实现,如std::allocator类、std::unique_ptr和std::shared_ptr模板来管理动态内存。
假设你的示例稍作修改:
class Foo{
private:
int x[100];
int *y;
public:
Foo()
{
y = new int[100];
}
~Foo()
{
delete[] y;
}
}
示例 1:
Foo *bar = new Foo();
Foo bar;
由于编译器和平台的类/结构对齐方式不同,实际大小可能略有差异。
类型为Foo的对象占用了100个按顺序存储的int的大小。如果你在堆栈上创建它,你将会把所有东西都放在堆栈上。如果你使用new来创建它,它将作为对象的一部分存在于堆中。
这是语言规范的一部分,我不确定你的问题是什么。
Foo
对象,那么成员数组x
将在堆上创建。当你为Foo
分配动态内存时,你正在请求长度为sizeof(Foo)
的内存(加上可能的一些内存开销,但让我们在此忽略这一点),在你的示例代码中,这意味着100个int
的大小。为了使类型为Foo
的对象(及其内部数据)跨范围存在,必须这样做。Foo
对象,且Foo
的内部数组不是指向在Foo
构造函数中使用new
分配的内存的指针,则该内部数组将在堆栈上创建。同样,为了使数组在作用域结束时自动清除而无需任何delete
,必须这样做。具体来说,struct Foo {
int* y;
Foo() : y(new int()) { }
~Foo() { delete y; }
};
无论 Foo
对象是在栈上还是堆上创建,都将在堆上创建 y
。
你的意思是
Foo* bar = new Foo();
我猜。 那个 是在堆中创建的。
new
动态地为数据在堆上分配内存。否则,像Foo bar
这样的调用会将本地数据推入堆栈。无论哪种情况,我都希望类指针严格分配在堆栈上。修饰符public
和private
如何影响分配方法? - sherrellbc