2010-06-22 111 views
3

当使用'new'创建数组并使用'delete'操作符删除数组时,delete知道数组的大小。正如其他SO线程中提到的,这个大小信息存储在元数据中。当使用new int [10]时元数据需要多少内存?

我的问题:元数据中究竟存储了什么,需要多少空间?它只是存储在元数据中的大小吗?

+1

标准只字未提它据我所知,依赖于实施我猜。 – 2010-06-22 04:36:48

回答

8

根据C++标准5.3。 0.4/12:

new T[5] results in a call of operator new[](sizeof(T)*5+x), 

< ...>其中x是表示阵列分配开销的非负非指定值。 < ...>开销的金额 可能因新的调用而不同。

+0

+1,感谢标准参考:) – 2010-06-22 04:42:07

0

这种问题是非常具体的编译器和plataform。每个编译器都以不同的方式实现它。该标准说什么应该实施,不完全如何实施。

当然,这个元数据必须包含数组大小或其他一些信息,这些信息可以让我们推断出它。否则,我们将无法调用数组中所有对象的析构函数。

4

它是实现定义的。我会说至少有四个字节的长度,但也可能有“下一个”和“前一个”指向相邻块的指针。运行时可能会有一个“魔术”数字,以确保您没有意外覆盖其内存部分等等。

但是你不应该为此担心。事实上,对于像你的int[10]这样的小数组(40字节),你可能会发现最大数量的空间实际上是通过填充占用的(例如,可能会添加24个字节的填充以使分配成为32 - 这可能由于性能原因做,说

在一天结束的时候,不过,正如我说,这完全取决于执行情况,以决定他们是如何做到这

0

这将取决于您的标准库。即使malloc()也需要数据来知道分配了多少字节。举一个例子,看看glibc的malloc的:

http://sourceware.org/git/?p=glibc.git;a=blob_plain;f=malloc/malloc.c;hb=HEAD

每个分配块的最低开销:4或8个字节

Each malloced chunk has a hidden word of overhead holding size 
    and status information. 
+0

这是一个特定的malloc实现。我写了一个指针值本身编码信息的东西 - 今天更加微不足道的是,它有64位指针。 – MSalters 2010-06-22 07:25:25

+0

@ MSalters:我很好奇以及为什么。我无法弄清楚我的头顶如何用通用的malloc做这件事(对于不同的对象大小没有不同的内存池) – 2010-06-22 07:36:57

+0

您得到了解决方案:针对不同对象大小的不同内存池。您通常可以从操作系统以小于4 KB的块分配内存,并且您需要的池数量相当有限。如果将分配的权重设置为2,则只有12个不同的池大小(最大为4KB)(操作系统直接分配4KB以上)。浪费最多为12 * 4KB,通常为12 * 2KB。这意味着当你有几千个小的分配时它就变得有效率,并不罕见。 – MSalters 2010-06-22 07:47:41