C ++对象块分配与个人分配

时间:2012-04-11 16:31:31

标签: c++ memory

块分配与单个对象分配的主要区别是什么。让我们说

int iCount = 5;

int i = 0;
while(i < iCount)
{
  f = new foo();
 i++;
}

//////////////////
foo* f = new foo[iCount];

第二种方法会为我节省一些内存空间吗? 我听说我们分配的每个对象都包含16个管理字节。所以块分配只使用一个头部保护。这是真的吗?。

2 个答案:

答案 0 :(得分:3)

您执行的每个分配还会分配分配标头(有时也会分配一些页脚保护结构),这取决于分配器使用的算法。 Here,你可以找到其中一种算法的描述。

当你分配一个数组时,将使用malloc()作为参数调用分配器(主要是sizeof(element) * count)并使用一个头结构将整个数组分配为一个块,因此它将引入更少的内存开销比逐个分配元素(见底部注释)。

无论如何(因为问题用标记),优秀的C ++程序员应该避免手动管理内存。对于数组,请使用标准库类(vectormaplist等)。尽可能使用RAII,不要使用原始指针,但是&#34; smart&#34;的。


注意:我在这里写的所有内容完全取决于所使用的算法,因此关于数组分配的段落可能不适用于所有可能的内存分配算法。因此,直接回答&#34;块分配与单个对象分配之间的市长差异是什么?#34;也与算法有关。

答案 1 :(得分:1)

另一个非常重要的区别是异常安全。在您的代码中:

int iCount = 5;
int i = 0;
while(i < iCount)
{
    f = new foo();
    i++;
}

你必须非常非常小心,不要因此而产生内存泄漏;你必须要记住所有foo能够在异常的情况下正确清理它。如果此代码在构造函数中,则在析构函数中释放是不够的,因为如果抛出异常,则对象永远不会生效,并且不会调用析构函数。这进一步传播到编写正确的拷贝构造和拷贝分配,每个异常安全等等。

道德:使用标准容器,例如vectorlistdeque(还有更多)。

//////////////////
foo* f = new foo[iCount];

如果在分配第一个和最后一个foo之间抛出异常,这至少会破坏每个构造的foo

当然,您必须注意f将被正确删除,特别是如果有其他投掷点执行此分配的代码。

道德:使用标准容器。手动内存管理乍一看似乎微不足道,特别是如果你来自C,但编写异常安全代码并非易事并且至关重要。