C++对象创建的内存分配

sof*_*sof 5 c++ memory-management object new-operator

在C类下面的对象创建过程中观察到不同大小的内存分配,

class C {
 int i;
 int j;
};

void f() {
 C *c = new C;
 C *c2 = new C[2];
 C (*c3)[2] = new C[2][2];
}
Run Code Online (Sandbox Code Playgroud)

c分配8个字节;

c2分配8*2 + 4字节;

c3分配有8*2*2 + 4字节.

为什么c2和c3再获取4个字节?

Ker*_* SB 8

请记住,C++将内存分配对象表达分开.默认的array-new表达式T * p = new T[N];既为N对象分配足够的内存,构造这些对象.在另一端,delete[] p;必须调用所有这些元素的析构函数,然后释放内存.

虽然平台处理分配和释放存储器,并且通过单个指针值足够好地识别可用存储器,但构造和销毁对象更复杂.实际对象的数量必须存储在某个地方,为此,标准允许C++实现请求更多的内存N * sizeof(T).确实,指针p总是指向N对象数组的开头,但p不一定是底层内存分配器返回的指针.(实际上,p保证准确地说是基础分配结果的值被超出的内存量所抵消.)

细节完全取决于实施.但是,有些平台提供了额外的保证; 例如,Itanium ABI(调用额外数据"数组cookie")表示内存new T[N]将按如下方式布局:

+- alignof(T) --+-- sizeof(T) --+-- sizeof(T) --+-- sizeof(T) --+-- ...
| ***** [8B: N] |  1st element  |  2nd element  |  3rd element  |  .....
+---------------+---------------+---------------+---------------+-- ...
A               A
|               |_ result of "new T[N]"
|
|_ value returned "operator new[]()"
Run Code Online (Sandbox Code Playgroud)