我看到在c++中有多种方法来分配和释放数据,我明白,当你调用malloc时你应该叫自由,当你使用新的操作符应与删除和对它是错误的把两个调用free()(例如,创建新的操作符),但是我不清楚我应该使用malloc / free,当我在现实世界中应该使用新的/删除程序。

如果你是c++专家,请告诉我你在这方面遵循的任何经验法则或惯例。


当前回答

New vs malloc()

1) new是操作符,malloc()是函数。

2) new调用构造函数,而malloc()不调用。

3) new返回准确的数据类型,而malloc()返回void *。

4) new从不返回NULL(失败时会抛出),而malloc()返回NULL

5)重新分配内存不能由new处理,而malloc()可以

其他回答

在c++中总是使用new。如果你需要一个无类型的内存块,你可以直接使用operator new:

void *p = operator new(size);
   ...
operator delete(p);

简短的回答是:如果没有真正好的理由,不要在c++中使用malloc。malloc在与c++一起使用时有许多缺陷,而new定义是为了克服这些缺陷。

c++代码中新修正的缺陷

malloc is not typesafe in any meaningful way. In C++ you are required to cast the return from void*. This potentially introduces a lot of problems: #include <stdlib.h> struct foo { double d[5]; }; int main() { foo *f1 = malloc(1); // error, no cast foo *f2 = static_cast<foo*>(malloc(sizeof(foo))); foo *f3 = static_cast<foo*>(malloc(1)); // No error, bad } It's worse than that though. If the type in question is POD (plain old data) then you can semi-sensibly use malloc to allocate memory for it, as f2 does in the first example. It's not so obvious though if a type is POD. The fact that it's possible for a given type to change from POD to non-POD with no resulting compiler error and potentially very hard to debug problems is a significant factor. For example if someone (possibly another programmer, during maintenance, much later on were to make a change that caused foo to no longer be POD then no obvious error would appear at compile time as you'd hope, e.g.: struct foo { double d[5]; virtual ~foo() { } }; would make the malloc of f2 also become bad, without any obvious diagnostics. The example here is trivial, but it's possible to accidentally introduce non-PODness much further away (e.g. in a base class, by adding a non-POD member). If you have C++11/boost you can use is_pod to check that this assumption is correct and produce an error if it's not: #include <type_traits> #include <stdlib.h> foo *safe_foo_malloc() { static_assert(std::is_pod<foo>::value, "foo must be POD"); return static_cast<foo*>(malloc(sizeof(foo))); } Although boost is unable to determine if a type is POD without C++11 or some other compiler extensions. malloc returns NULL if allocation fails. new will throw std::bad_alloc. The behaviour of later using a NULL pointer is undefined. An exception has clean semantics when it is thrown and it is thrown from the source of the error. Wrapping malloc with an appropriate test at every call seems tedious and error prone. (You only have to forget once to undo all that good work). An exception can be allowed to propagate to a level where a caller is able to sensibly process it, where as NULL is much harder to pass back meaningfully. We could extend our safe_foo_malloc function to throw an exception or exit the program or call some handler: #include <type_traits> #include <stdlib.h> void my_malloc_failed_handler(); foo *safe_foo_malloc() { static_assert(std::is_pod<foo>::value, "foo must be POD"); foo *mem = static_cast<foo*>(malloc(sizeof(foo))); if (!mem) { my_malloc_failed_handler(); // or throw ... } return mem; } Fundamentally malloc is a C feature and new is a C++ feature. As a result malloc does not play nicely with constructors, it only looks at allocating a chunk of bytes. We could extend our safe_foo_malloc further to use placement new: #include <stdlib.h> #include <new> void my_malloc_failed_handler(); foo *safe_foo_malloc() { void *mem = malloc(sizeof(foo)); if (!mem) { my_malloc_failed_handler(); // or throw ... } return new (mem)foo(); } Our safe_foo_malloc function isn't very generic - ideally we'd want something that can handle any type, not just foo. We can achieve this with templates and variadic templates for non-default constructors: #include <functional> #include <new> #include <stdlib.h> void my_malloc_failed_handler(); template <typename T> struct alloc { template <typename ...Args> static T *safe_malloc(Args&&... args) { void *mem = malloc(sizeof(T)); if (!mem) { my_malloc_failed_handler(); // or throw ... } return new (mem)T(std::forward(args)...); } }; Now though in fixing all the issues we identified so far we've practically reinvented the default new operator. If you're going to use malloc and placement new then you might as well just use new to begin with!

我以前玩过很少的计算机图形C/ c++应用程序。 过了这么久,有些东西消失了,我很想念它们。

关键是,malloc和new,或free和delete,可以同时工作, 特别是对于某些基本类型,这是最常见的。

例如,一个char数组可以用malloc或new来分配。 一个主要的区别是,使用new,你可以实例化一个固定的数组大小。

char* pWord = new char[5]; // allocation of char array of fixed size 

在这种情况下,不能使用变量来表示数组的大小。 相反,malloc函数可以允许变量大小。

int size = 5; 
char* pWord = (char*)malloc(size); 

在这种情况下,可能需要一个转换强制转换操作符。 对于malloc返回的类型,它是指向void的指针,而不是char。 有时候编译器不知道如何转换这个类型。

分配内存块后,可以设置变量值。 对于一些较大的数组,memset函数确实会慢一些。 但是在赋值之前,所有的bit必须先设置为0。 因为数组的值可以有任意的内容。

假设,数组被分配给另一个较小的数组。 数组元素的一部分仍然可以有任意内容。 在这种情况下,建议调用memset函数。

memset((void*)pWord, 0, sizeof(pWord) / sizeof(char)); 

分配函数可用于所有C包。 这些是通用函数,必须适用于更多的C类型。 c++库是旧C库的扩展。 因此malloc函数返回一个泛型void*指针。 该结构没有定义new或delete操作符。 在这种情况下,可以使用malloc分配自定义变量。

new和delete关键字实际上是一些定义好的C操作符。 也许一个自定义联合或类可以定义这些操作符。 如果在类中没有定义new和delete,则它们可能不起作用。 但如果一个类是由另一个类派生的,这个类有这些操作符, new和delete关键字可以具有基本的类行为。

关于释放数组,free只能与malloc结合使用。 不能使用malloc分配变量,然后使用delete释放变量。

简单的删除操作符只引用数组的第一项。 因为pWord数组也可以写成:

pWord = &pWord[0]; // or *pWord = pWord[0]; 

当必须删除一个数组时,使用delete[]操作符:

delete[] pWord; 

类型转换并不坏,只是不适用于所有的变量类型。 转换类型转换也是一个必须定义的运算符函数。 如果没有为某个类型定义此操作符,则它可能不起作用。 但并不是所有的错误都是由这个转换强制转换操作符引起的。

另外,在使用自由调用时,必须使用到空指针的类型转换。 这是因为free函数的实参是一个空指针。

free((void*)pWord); 

可能会出现一些错误,因为数组的大小太小。 但这是另一个故事,并不是因为使用了演员阵容。

致以亲切的问候,艾德里安·布里纳斯

如果你有C代码,你想移植到c++,你可能会留下任何malloc()调用。对于任何新的c++代码,我建议使用new。

malloc()在C语言中用于动态分配内存 而在c++中,同样的工作由new()完成。 所以你不能混合两种语言的编码习惯。 如果你问calloc和malloc()之间的差异,那就好了