我的问题是关于数组,不是对象。
关于malloc()
/ free()
与new
/ delete
的关于SO的一些问题,但所有这些问题都集中在它们的使用方式上的差异。我理解它们是如何使用的,但我不明白底层差异会导致使用上的差异。
我经常听到C程序员说malloc()
和free()
操作费用很高,但我从来没有听说过C ++程序员对new
和delete
的说法。我还注意到C ++没有与C realloc()
对应的操作。
如果我正在编写C ++的vector
类的等价物,我希望避免在调整整个数组时复制整个数组,但是必须复制new
和delete
。在C中,我只是realloc()
。值得注意的是realloc()
可能只是复制整个数组,但我的印象是它使用相同的指针并为其分配更少的空间,至少在调整大小时。
所以我的问题是,malloc()
和free()
使用的算法与new
和delete
使用的算法有何不同。更具体地说,为什么C方式有一个更昂贵的耻辱,为什么C ++方式不允许在不复制的情况下调整大小?
答案 0 :(得分:5)
引擎盖下没有真正的区别 - 通常默认的new
和delete
运营商只需拨打malloc
和free
。
至于“更贵的耻辱”,我的理论是这样的:在当天,每个周期都计算在内,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 ++并不那么担心。
new
和delete
可能由编译器以与malloc非常类似的方式实现,但它们有一个区别(这就是它们存在的原因) - 它们调用构造函数和析构函数相关项目。
当我说构造函数时,我当然意味着需要进行任何初始化(填写VTABLES,设置初始化程序等)。这可能会使new
和delete
变慢,但在并排比较中(例如,分配和释放int
)没有根本区别。
答案 5 :(得分:0)
他们从根本上使用相同的技术进行分配 - 当然,在大多数实现中,默认的C ++运行时new不会比malloc快得多。其中一个最大的区别是你可以用C ++重写allocator,这样你就可以使用针对你预期的内存行为进行优化的分配器了 - 你当然也可以在C语言中做到这一点,但是语法方面有点麻烦。