C++:malloc和new是否等价?

3

1
你尝试过两者吗?你有观察到任何不同吗? - abelenky
我正在尝试在炼金术中使用它,但我发现顺序完全不同。那么,memblock = new char[currentByteLength]的等效语句是什么? - karthick
4
那不是发现语言运作方式的好方法。你需要阅读文档。就拿这个例子来说,行为不会有明显区别。然而,malloc和new是非常不同的! - John Dibling
4
好的,以下是需要翻译的内容:Duplicate1在 C++ 中,new 和 delete 运算符用于动态地分配和释放内存。malloc() 和 free() 函数也可以用于相同的目的。它们之间的主要区别是 new 和 delete 运算符会调用对象的构造函数和析构函数,而 malloc() 和 free() 函数只会分配和释放内存块。duplicate2在 C++ 中,你应该使用 new 和 delete 运算符来动态地分配和释放内存,特别是当你需要为自定义类型分配内存时。malloc() 和 free() 函数则更适合在 C 代码中使用。duplicate3在 C++ 中,new 和 delete 运算符用于动态地分配和释放内存。这些运算符比 malloc() 和 free() 函数更安全、更易于使用,因为它们可以调用对象的构造函数和析构函数。duplicate4在 C++ 中,new 运算符和 malloc() 函数都可以用于动态地分配内存。但是,new 运算符会调用对象的构造函数,而 malloc() 函数不会。另外,calloc() 函数可以用于动态地分配并初始化内存块。 - user1481860
@Øystein也许应该在问题中提到malloc和new时显示警告 :) - Foo Bah
1
@karthick - 注意了,这里大多数SO的人并不真正理解这个问题。例如,最高票答案的第一句话就是完全错误的。两个版本都没有在堆上分配内存。自由存储区(new分配的)可能使用堆来实现,但不一定要这样做。请看我的回答。 - Edward Strange
10个回答

8
memblock = (char *)malloc( currentByteLength); 

memblock = new char[currentByteLength];

现在没有区别。但是如果将char替换为int,那么就会有区别,因为在这种情况下,malloc将分配大小为currentByteLength的内存,而new将分配大小为size(int) * currentByteLength的内存。所以一定要非常小心。
此外,如果您在new表达式中提到的类型是用户定义的类型,则会调用默认构造函数currentByteLength次,以构造对象!
对于内置类型,没有构造函数!

正确,这将需要malloc * sizeof(int)。但你错过了重点,真正的区别在于构造函数/析构函数的调用。 - Stefan Steiger
@Quandary:我也加上了。事实上,当你写那个评论的时候,我正在添加它! - Nawaz
1
为什么这个被踩了?他说的是正确的。 - Argote
2
似乎有人在这里对几乎每个答案进行了负面评价...不确定这样做的意义何在。希望他们能解释一下为什么这样做。 - tenfour
@给踩的人:你们能否解释一下为什么要踩这个帖子?它有什么问题吗?请指出来。 - Nawaz
@Nawaz:我给你点了踩,因为mallocnew[]的作用不同。malloc必须与free匹配,而new[]必须与delete[]匹配。 - Mankarse

3
几乎是的。我的意思是,它们都在堆上分配数据,并且在处理 char 或 int 等基本类型时,大致相同。然而,在处理对象时存在重要差异。new 调用对象的构造函数,而 malloc 不会。这是因为 malloc 是 C 函数,不知道类的任何信息。
通常情况下,在 C++ 中动态分配内存的首选方法是使用 new,因为它是类型安全且易于使用的。没有任何阻止你使用 malloc,但是不要混用它们:不要对使用 malloc 分配的内存调用 delete,也不要对使用 new 分配的内存调用 free。否则会发生糟糕的事情。并且不要对使用 new[] 创建的数组调用 delete,也不要对使用 new 创建的对象调用 delete[](是的,我知道这很令人困惑,这就是你应该使用 vector 的原因)。

在C++风格中,与realloc等效的是什么? - Foo Bah
另外:malloc总是需要一个free,而这个new需要一个delete[]而不是delete。 - wilhelmtell
@Foo Bah 没有。您必须“new”另一个缓冲区并将原始数据复制到其中,然后释放原始缓冲区。无论如何,请使用“vector”。 - Etienne de Martel
@wilhelmtell 哎呀,真不敢相信我居然忘了那个!谢谢! - Etienne de Martel
如果这两个表达式产生相同大小的内存,那是因为它们都要求 char。但是更改为 int 后,这两个表达式将要求两种不同的大小。(第一个表达式应该是 currentByteLength*sizeof(T) - wilhelmtell
@Etienne 有一些使用情况下,malloc 是更优选的 :) - Foo Bah

3
如果内存块是通过malloc()分配的,则必须调用free()释放它。如果是通过new[]分配的,则必须通过调用delete []来删除它。使用错误的处理方法是一个错误。
另外,当您分配对象数组时,newmalloc的行为非常不同。
此外,它们在报告内存不足条件时也有所不同-new会抛出异常,malloc返回零。

2
“new”关键字在“自由存储区”中分配内存,“malloc”函数在“堆”中分配内存。
许多实现使用堆来实现自由存储区,但它们不一定有任何关系。它们可以完全由不同的管理器处理。
就您的代码而言,由您的特定示例分配的内存块可以被视为等效的。这是一个相当特殊的情况,但您仍然需要确保在正确的位置(自由存储区 vs. 堆)释放该块。最好的方法是根本不将它们视为相同的东西。
这是有关C ++内存的良好教程:http://www.gotw.ca/gotw/009.htm

1

不完全正确,malloc() 是 C 函数,而 new 是 C++ 运算符,此外,如果在你的情况下它们都分配缓冲区,但是如果 malloc() 失败,则返回 NULL。但是如果 new 失败,则会抛出异常。

要了解更多信息,请阅读C++ FAQ 中的此会话


1

简短回答:是的,这就是在C++中动态分配内存的方法。

长篇回答:不,它们是不同的东西。最明显的区别是使用malloc()分配的内存必须使用free()释放,而使用new分配的内存必须使用delete释放。

new调用类型的默认构造函数,是类型安全的,在出错时会抛出异常,并且可以被覆盖。

在C++中,除非需要与用C编写的代码进行接口交互,否则应始终使用new而不是malloc()


0
请注意:
memblock = new DATATYPE[length]

等同于

memblock = (DATATYPE*) malloc(length * sizeof(DATATYPE));

只有在没有构造函数的情况下,并且数据类型本身不是指针时,才成立。

只有在没有析构函数的情况下,free和delete才是等效的。

如果没有构造函数/析构函数,您可以互换地使用new/malloc和delete/free,甚至混合使用。

new和delete会调用构造函数/析构函数(如果可用)来为新对象创建内存,而malloc和free只是分配内存(不调用构造函数/析构函数)。


0

是的:

  1. 它们有不同的拼写(废话 :P)
  2. 它们需要不同的内存释放方法(malloc / free vs. operator new[] / operator delete[]
  3. 当它们失败时,它们具有不同的行为。`malloc`返回0,`operator new[]`抛出异常。

然而,这只是在您特定的情况下。在以下情况下,差异甚至更大:

  1. 您正在分配非POD对象(在这里,将调用构造函数和析构函数)
  2. 元素的大小不是char大小(在这里,您需要进行一些math运算以获取malloc -- 这将说明如何使用对象而不是 blob 来分配内存更加直观)

我认为这不是一个好问题...你真正想问什么?区别是什么?不,您不能盲目地互换它们。


@above:那么,memblock = new char[currentBytelength]的等效语句是什么? - karthick

0

如果char大小为1字节,则在除了异常/空值和构造函数之外的情况下,它大致相当。否则,在第一个中,您应该乘以数据类型大小。

memblock = (char *)malloc( currentByteLength * sizeof(char) ); 

1
sizeof(char)的大小是根据定义确定的。 - Mike Seymour

0

主要的区别(特指char)如下:

  • 如何在最后清除内存(第一个使用free,第二个使用delete)
  • 大小可能不同(如果char实际上是一个宽2字节字符,则第一个只分配足够当前字节长度的空间,而新的则分配当前字节长度*2个字节)
  • malloc将通过返回null失败,但new将抛出运行时异常

顺便提一下:应该始终对malloc进行sizeof检查:

memblock = (char *)malloc( sizeof(char) * currentByteLength); 

sizeof(char) 的大小根据定义是1。 - Mike Seymour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接