这可能是一个微不足道的问题 - 每个人都知道用“new”运算符创建的对象是在堆上分配的,但如果对象真的很复杂,有一些成员,局部变量等怎么办?所有这些存储在哪里?
假设我有类Engine的对象,非常复杂。在我的代码的某处,我这样做:
Engine* e = new Engine;
所以很简单,指针进入堆栈并在堆上创建Engine的新实例。但是在类Engine中,我有一个不是指针的字段 - 这个字段在这种情况下存储在哪里?如果在Engine类中我有一个使用局部变量的方法 - 那么那些存储在堆上的那些呢?
答案 0 :(得分:1)
结构/类的成员存储在为该结构/类的对象实例分配的内存块中(无论是在堆栈上还是堆都无关紧要,但取决于对象的分配方式) )。内存中对象的大小是其数据成员的总大小,以及编译器在它们之间添加的任何填充以用于对齐目的。
new type
分配一块至少 sizeof(type)
字节的动态内存块(可能更多用于内存管理器开销),然后调用类型的构造函数记忆块。
所以,例如,如果你有这个类:
class Engine
{
private:
int numOfThings;
...
};
然后该类的任何实例占用sizeof(Engine)
个字节的内存,其中前4个字节被numOfThings
成员占用。那可能是自动记忆:
Engine engine;
或者它可能是动态记忆:
Engine *engine = new Engine;
现在,我们可以说Engine
有其他自动或动态成员,例如:
class Engine
{
private:
int numOfThings;
uint32_t values[16];
std::string name;
uint8_t *data;
Engine()
{
data = new uint8_t[256];
}
~Engine()
{
delete[] data;
}
};
value
成员的大小为(sizeof(uint32_t) * 16)
(4 * 16 = 64)个字节,并添加到Engine
类的总大小。
name
成员的大小为sizeof(std::string)
个字节(根据STL实现而有所不同),它被添加到Engine
类的总大小中。但是,内部std::string
有一个指向动态内存的指针,它为字符数据分配。该内存的大小不包含在Engine
类的总大小中。
data
指针的大小为sizeof(uint8_t*)
个字节(32位系统为4,64位系统为8),它被添加到Engine
类的总大小。 data
指向的内存块大小为(sizeof(uint8_t) * 256)
(1 * 256 = 256)个字节,并存储在动态内存的其他位置。
在类方法中声明为局部变量的变量不是类本身的一部分,因此不计入其大小。只有在类定义中声明的数据成员才会计入其大小。