C++ 上的内存分配对象创建
下面在类 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];
}
c 分配了 8 个字节;
c2分配了8*2+4字节;
c3分配了8*2*2+4字节。
为什么c2和c3多需要4个字节?
The different size of memory allocation is observed during the object creation on class C below,
class C {
int i;
int j;
};
void f() {
C *c = new C;
C *c2 = new C[2];
C (*c3)[2] = new C[2][2];
}
c is allocated with 8 bytes;
c2 is allocated with 8*2+4 bytes;
c3 is allocated with 8*2*2+4 bytes.
Why does c2 and c3 aquire 4 more bytes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
请记住,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]
的内存布局如下:Remember that C++ separates memory allocation and object expression. The default array-new expression
T * p = new T[N];
both allocates enough memory forN
objects and constructs those objects. At the other end,delete[] p;
must call the destructor of all those elements, and then free the memory.While allocating and freeing memory is handled by the platform, and freeable memory is sufficiently well identified to the OS by a single pointer value, constructing and destroying objects is more complicated. The number of actual objects must be stored somewhere, and to that end, the standard permits a C++ implementation to request more memory than
N * sizeof(T)
. It is true that the pointerp
will always point to the beginning of the array ofN
objects, butp
does not have to be the same pointer that was returned by the underlying memory allocator. (In fact,p
is guaranteed to be precisely the value of the underlying allocation result offset by the excess amount of memory.)The details are entirely left up to the implementation. Some platforms provide additional guarantees, though; for example, the Itanium ABI (which calls the extra data "array cookie") says that the memory for
new T[N]
will be laid out as follows:根据标准(
[expr.mew]
部分):显然,该标准期望使用动态分配的数组来存储一些附加信息。
现在,使用调试器查看这些额外字节中填充的内容,并找出编译器何时需要额外信息来完成其工作。
(提示:修复您的程序,使其不会泄漏内存)
From the standard (section
[expr.mew]
):Clearly the standard expects some additional information to be stored with a dynamically allocated array.
Now, use your debugger to see what's stuffed into those extra bytes, and figure out when that extra information might be needed for the compiler to do its job.
(Hint: fix your program so that it doesn't leak memory)
许多编译器使用 new[] 返回的指针之前的 4 个字节来存储实际分配的对象数量。这完全取决于实现,重要的是要记住,指针算术将您带到分配的内存范围之外会导致未定义的行为
A lot of compilers use the 4 bytes before the pointer returned from new[] to store the number of objects actually being allocated. This is all implementation dependent and it's important to remember that pointer arithmetic that takes you outside the range of memory you allocated results in undefined behavior