如何在C和C ++中分配和释放* array *内存?

时间:2009-08-20 08:23:35

标签: c++ c arrays memory-management

我的问题是关于数组,不是对象。

关于malloc() / free()new / delete的关于SO的一些问题,但所有这些问题都集中在它们的使用方式上的差异。我理解它们是如何使用的,但我不明白底层差异会导致使用上的差异。

我经常听到C程序员说malloc()free()操作费用很高,但我从来没有听说过C ++程序员对newdelete的说法。我还注意到C ++没有与C realloc()对应的操作。

如果我正在编写C ++的vector类的等价物,我希望避免在调整整个数组时复制整个数组,但是必须复制newdelete。在C中,我只是realloc()。值得注意的是realloc()可能只是复制整个数组,但我的印象是它使用相同的指针并为其分配更少的空间,至少在调整大小时。

所以我的问题是,malloc()free()使用的算法与newdelete使用的算法有何不同。更具体地说,为什么C方式有一个更昂贵的耻辱,为什么C ++方式不允许在不复制的情况下调整大小?

6 个答案:

答案 0 :(得分:5)

引擎盖下没有真正的区别 - 通常默认的newdelete运营商只需拨打mallocfree

至于“更贵的耻辱”,我的理论是这样的:在当天,每个周期都计算在内,malloc所花费的时间在很多情况下确实很重要。但到了C ++出现的时候,硬件速度要快得多,而免费商店经理花费的时间也不那么重要了。重点是从有效使用机器资源转向有效使用程序员资源。

为什么C ++缺少realloc等价物,我不知道。

答案 1 :(得分:2)

通常new和delete使用malloc()和free()进行内存分配/释放。无论如何,他们必须使用一些原语进行内存分配/释放 - 重载 new delete 运算符,这些运算符可能比malloc()和free()更快(比如它可以是在固定大小的对象的内存池上工作的函数。通常,除非你实际上已经完成了这样的重载,否则你不会看到每种方式完成内存分配的成本差异。

不允许重新分配,因为并非所有数据类型都允许在内存中移动 - 它们需要复制构造函数和调用的析构函数才能正确移动。例如,您可能在阵列中存储了一些图形节点结构。如果你盲目地移动它们,指向对象之间的指针将变为无效。

答案 2 :(得分:1)

“新的和删除可能是昂贵的操作” - 那里,你现在有 听说C ++程序员说出来了。但严重的是,动态内存分配在两种语言中都是相同的。

答案 3 :(得分:1)

我不知道C“耻辱”,但是为了调整C ++的大小。您可以使用placement new来自定义new的行为。

但为什么呢?让编译器制造商做他们最擅长的事情!

答案 4 :(得分:1)

为了彻底概括,C传统上一直被用于更多资源受限的环境中,因为它的使用时间更长,并且因为它在嵌入式应用程序中使用。因此,malloc的潜在计算成本令人担忧,而在PC上更常用的C ++并不那么担心。

newdelete可能由编译器以与malloc非常类似的方式实现,但它们有一个区别(这就是它们存在的原因) - 它们调用构造函数和析构函数相关项目。

当我说构造函数时,我当然意味着需要进行任何初始化(填写VTABLES,设置初始化程序等)。这可能会使newdelete变慢,但在并排比较中(例如,分配和释放int)没有根本区别。

答案 5 :(得分:0)

他们从根本上使用相同的技术进行分配 - 当然,在大多数实现中,默认的C ++运行时new不会比malloc快得多。其中一个最大的区别是你可以用C ++重写allocator,这样你就可以使用针对你预期的内存行为进行优化的分配器了 - 你当然也可以在C语言中做到这一点,但是语法方面有点麻烦。