块分配与单个对象分配的主要区别是什么。让我们说
int iCount = 5;
int i = 0;
while(i < iCount)
{
f = new foo();
i++;
}
//////////////////
foo* f = new foo[iCount];
第二种方法会为我节省一些内存空间吗? 我听说我们分配的每个对象都包含16个管理字节。所以块分配只使用一个头部保护。这是真的吗?。
答案 0 :(得分:3)
您执行的每个分配还会分配分配标头(有时也会分配一些页脚保护结构),这取决于分配器使用的算法。 Here,你可以找到其中一种算法的描述。
当你分配一个数组时,将使用malloc()
作为参数调用分配器(主要是sizeof(element) * count
)并使用一个头结构将整个数组分配为一个块,因此它将引入更少的内存开销比逐个分配元素(见底部注释)。
无论如何(因为问题用c++标记),优秀的C ++程序员应该避免手动管理内存。对于数组,请使用标准库类(vector
,map
,list
等)。尽可能使用RAII,不要使用原始指针,但是&#34; smart&#34;的。
注意:我在这里写的所有内容完全取决于所使用的算法,因此关于数组分配的段落可能不适用于所有可能的内存分配算法。因此,直接回答&#34;块分配与单个对象分配之间的市长差异是什么?#34;也与算法有关。
答案 1 :(得分:1)
另一个非常重要的区别是异常安全。在您的代码中:
int iCount = 5;
int i = 0;
while(i < iCount)
{
f = new foo();
i++;
}
你必须非常非常小心,不要因此而产生内存泄漏;你必须要记住所有foo
能够在异常的情况下正确清理它。如果此代码在构造函数中,则在析构函数中释放是不够的,因为如果抛出异常,则对象永远不会生效,并且不会调用析构函数。这进一步传播到编写正确的拷贝构造和拷贝分配,每个异常安全等等。
道德:使用标准容器,例如vector
,list
或deque
(还有更多)。
//////////////////
foo* f = new foo[iCount];
如果在分配第一个和最后一个foo
之间抛出异常,这至少会破坏每个构造的foo
。
当然,您必须注意f
将被正确删除,特别是如果有其他投掷点执行此分配的代码。