类成员的内存分配
Class members memory allocation
我的问题主要是理论性的。假设我们有一个类
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
实例中,但它指向的内存将位于内存中的某个地方,但我们不知道在哪里。当实例被销毁时,b
将自动被清理,但a
将需要在析构函数中进行特殊处理,否则内存将泄漏。你可以像
A
+------+ +----------+
| a->+---| 100 ints |
| b | +----------+
+------+
就效率而言,就像一些程序员提到的那样,你不应该真的担心这个。你应该使用你认为适合这份工作的类型。一旦你启动并运行它,你就可以分析它,找到瓶颈在哪里。如果你发现由于使用指针导致了太多的缓存丢失,那么你可以考虑尝试将数据定位到类本身。
我还想提一下,如果你发现自己写的是some_type* name = new/new[]
,那么你应该考虑使用std:unique_ptr<some_type>/std:unique_ptr<some_type[]>
或std::vector<some_type>
。
不,你不完全正确。
a
和b
是对象内部的变量。它们都扩展了类的大小——至少扩展了sizeof(int*)
的大小。
根据你构造对象的方式,这些变量的内存是在堆栈或堆上分配的,正如你已经提到的:
new A/int/etc
在堆上分配内存
A/int/etc. var
在栈上分配内存
a = new int[100];
不是类对象的一部分。它是一些外部数据。在您的类对象中,您只有一个int*
成员(大小为4-8字节,取决于体系结构)指向该数据。
首先,成员原始指针(例如MyClass
)的缺点是它强制#include
声明MyClass
的头。这可能导致编译缓慢。为了解决这个问题,你可以使用带有向前声明的智能指针。
第二个问题是将类的所有成员存储在堆内存或堆栈内存中更有效吗?
通常最好仅在必要时使用指针。通常应该在类中将成员声明为值。它将是局部的,出错的机会更少,分配更少,最终可能出错的事情更少,编译器总是可以知道它在指定的偏移量处,所以……
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 给定一个指向堆分配内存的指针,智能指针实现如何为其找到合适的释放函数?
- 如果 const 不分配内存,为什么我可以获取 const 的地址?
- 在函数中分配内存时出现问题
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- constexpr new 如何分配内存?
- 在构造函数中分配内存失败是如何冒泡的
- LLVM 传递以在特定地址分配内存
- CudaMalloc 在分配内存时失败
- 为什么它在不分配内存的情况下工作正常
- 为什么在正确解除分配内存时出现内存泄漏?
- 如何通过 malloc 为队列数组分配内存?
- vector是否为std::移动的对象连续分配内存
- 删除类成员的动态分配内存的最佳方法是什么
- 唯一指针是否在堆或堆栈上分配内存?
- 如果不分配内存,我如何能够为变量创建和分配值?
- std::initializer_list 堆是否分配内存?
- 如何按顺序或在指定的地址分配内存?
- 是否可以使用 malloc 为类对象分配内存?
- 迭代器是否分配内存(如指针)?