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

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


当前回答

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

其他回答

从较低的角度来看,new将在提供内存之前初始化所有内存,而malloc将保留内存的原始内容。

简短的回答是:如果没有真正好的理由,不要在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++,尝试使用new/delete而不是malloc/calloc,因为它们是操作符。对于malloc/calloc,需要包含另一个头文件。不要在同一代码中混合使用两种不同的语言。它们的工作在各个方面都是相似的,都是从哈希表的堆段动态分配内存。

只使用malloc和free来分配将由以c为中心的库和api管理的内存。对你控制的所有东西使用new和delete(以及[]变量)。

很少考虑使用malloc/free而不是new/delete的情况是,当你使用realloc进行分配和重新分配(简单的pod类型,而不是对象)时,因为在c++中没有类似于realloc的函数(尽管这可以使用更c++的方法来完成)。