2009-08-20 84 views
4

我的问题具体是关于数组,而不是对象。在C和C++中如何分配和释放* array *内存?

上有大约SO malloc()/free()new/delete,但他们都专注于如何使用它们的差异的几个问题。我了解它们是如何使用的,但我不明白底层差异会导致使用差异。

我经常听到的C程序员说malloc()free()是昂贵的操作,但我从来没有听说过一个C++程序员说,这大约newdelete。我也注意到C++没有对应于C的realloc()的操作。

如果我正在写一个等价于C++的vector类,我想避免在调整它的大小时复制整个数组,但需要复制newdelete。在C中,我只是realloc()。值得注意的是,realloc()可能只是复制整个阵列,但我的印象是,它使用了相同的指针并为其分配了更少的空间,至少在确定尺寸时是如此。

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

+1

realloc的是相当时髦,这取决于实际的参数和当前存储器使用它将ALLOC,删除,就地或realloc并移动(并因此无效其它指针)的realloc。即你不能从代码中看到它会做什么。 – 2009-08-20 08:27:35

回答

5

在引擎盖下没有真正的区别 - 通常默认的newdelete运营商将简单呼叫到mallocfree

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

为什么C++缺乏realloc等同,我不知道。

+1

,因为realloc,很多时候,只是分配一个新块,将旧数据复制到新块,然后释放原始块。 如果你想有一个动态可扩展阵列使用std ::矢量 – Goz 2009-08-20 08:33:22

+0

早在一天?那么,看看malloc的代码,你会发现为什么它今天可能是昂贵的。你为什么认为有效的垃圾收集有太多的研究?如果有的话,今天情况会更糟,因为代码中有很多alloc/free,没有太多的成本。 – xcramps 2009-08-20 08:35:01

+0

@xcramps:我说的是,这是一个感知问题,而不是有形的技术差异。 – RichieHindle 2009-08-20 08:36:58

0

他们从根本上使用相同的技术用于分配 - 当然,对大多数实现,默认的C++运行时新的不会比malloc的速度要快得多。最大的区别之一就是你可以用C++重写allocator,这样你就可以使用优化你的预期内存行为的分配器 - 当然你也可以用C来做到这一点,但它在语法上有点繁琐。

1

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

+0

实际上,它“可以”花费更多的钱做一个新的,因为构造函数被称为每个项目... – Goz 2009-08-20 08:33:53

+1

@Goz。原始类型的构造函数什么都不做,任何像样的编译器都会乐于将它们优化出来。 – sharptooth 2009-08-20 08:36:30

+0

因此,为什么我把罐子放在引号中... – Goz 2009-08-20 09:46:06

1

我不知道关于C “柱头”,但对于调整C++。您可以使用新的展示位置来自定义新行为。

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

+0

你有没有关于如何去做这件事的任何链接? – Imagist 2009-08-20 08:31:55

+0

@Imagist:http://en.wikipedia.org/wiki/Placement_syntax – RichieHindle 2009-08-20 08:50:39

2

常新和删除使用malloc()和free()内存分配/释放。无论如何,他们必须使用一些原语内存分配/重新分配 - 与超载删除运算符可能是更快的malloc()和free()(说它可以是功能工作的内存池的固定大小对象)。通常情况下,除非你实际上已经完成了这样的超载,否则你不会看到以这些方式完成的内存分配成本的任何差异。

再分配不是简单地允许的,因为不是所有的数据类型允许在内存中移动 - 他们需要拷贝构造函数和析构函数调用来正确地移动。例如,你可能有一些图节点结构存储在一个数组中。如果您盲目移动它们,指向对象之间的指针将会失效。

1

为深入推广,C历来在更受限制的资源环境下使用,这既是因为它的存在了更长,因为它是在嵌入式应用中使用。因此,潜在的计算成本malloc是一个担心,而PC上更常用的C++并不担心这么多。

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

当我说的构造函数,我这样做当然意味着所需的任何初始化(填写虚函数表,设置initialisers等)。这可以潜在地使newdelete慢,但在通过并排比较(分配和释放一个int例如)侧没有根本区别。