我的问题主要是理论性的。假设我们有一个类
class A{
private:
int * a;
int b;
private:
A(){
a = new int[100];
b = 100;
}
~A(){
delete [] a;
}
}
据我所知,如果我们动态创建 A 类型的对象 (A * a = new A()
),这个对象的内存将在堆中分配,如果我使用 ( A a
) 它将在堆栈 (A a)
上创建。如果在堆栈上创建对象,变量a
的内存将分配到堆上,如果我们在堆上分配对象,对象b
的内存将分配到堆栈上。我要确定的第一个问题:我是对的吗?
第二个问题,将类的所有成员存储在堆内存或堆栈内存中会更有效吗?
class A{
private:
int * a;
int * b;
private:
A(){
a = new int[100];
b = new int(100);
}
~A(){
delete [] a;
delete b;
}
}
当我说高效时,我的意思是关于类成员的所有数据将在堆或堆栈的内存中彼此靠近存储(实际上我不确定它们将彼此靠近存储是否正确)。
最佳答案
首先,C++ 中没有堆或栈。相反,我们有自动存储持续时间和动态存储持续时间。具有自动存储持续时间的对象是作用域对象。当它超出范围时,它会自动清理。另一方面,具有动态存储持续时间的对象不受其范围的限制。它的生命周期仅在程序明确结束时结束(通常这意味着调用 delete
)。
现在 A
您存储了一个自动存储持续时间的对象,b
,以及一个具有动态存储持续时间的,a
.这意味着 b
将住在A
的任何地方实例生活。 a
也住在A
内instance 但它指向的内存将驻留在内存中的某个地方,但我们不知道在哪里。当实例被销毁时b
会自动清理但是a
将需要在析构函数中进行特殊处理,否则内存将泄漏。你可以像这样想象它
A
+------+ +----------+
| a->+---| 100 ints |
| b | +----------+
+------+
就效率而言 Some programmer dude提到你不应该真的担心那个。你应该使用你认为适合这份工作的类型。一旦启动并运行,您就可以对其进行分析以找到瓶颈所在。如果您因为使用指针而发现太多缓存未命中,那么您可以考虑尝试将数据本地化到类本身。
如果您发现自己在写 some_type* name = new/new[]
,我还想提一下那么你应该考虑使用 std:unique_ptr<some_type>/std:unique_ptr<some_type[]>
或 std::vector<some_type>
.
关于c++ - 类成员内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40487239/