在什么情况下我应该使用malloc和/或new? 我在C++中看到有多种方法来分配和释放数据,我知道当你调用 MalOC 时,你应该调用免费< />代码,当你使用新< /Calp>运算符时,你应该与删除> /CODE >配对。在使用new操作符创建的东西上),但我不清楚在我的真实程序中何时应该使用malloc/free以及何时应该使用new/delete 如果你是C++专家,请告诉我你在这方面遵循的任何规则或规则。 < P>除非你被迫使用C,否则你应该永远不要使用< /强> MalOC 。始终使用new
如果您需要大量数据,只需执行以下操作:在什么情况下我应该使用malloc和/或new? 我在C++中看到有多种方法来分配和释放数据,我知道当你调用 MalOC 时,你应该调用免费< />代码,当你使用新< /Calp>运算符时,你应该与删除> /CODE >配对。在使用new操作符创建的东西上),但我不清楚在我的真实程序中何时应该使用malloc/free以及何时应该使用new/delete 如果你是C++专家,请告诉我你在这方面遵循的任何规则或规则。 < P>除非你被迫使用C,否则你应该永远不要使用< /强> MalOC 。始终使用new,c++,memory-management,malloc,new-operator,C++,Memory Management,Malloc,New Operator,如果您需要大量数据,只需执行以下操作: char *pBuffer = new char[1024]; 尽管这是不正确的,但要小心: //This is incorrect - may delete only one element, may corrupt the heap, or worse... delete pBuffer; 相反,您应该在删除数据数组时执行此操作: //This deletes all items in the array delete[] pBuffer; >
char *pBuffer = new char[1024];
尽管这是不正确的,但要小心:
//This is incorrect - may delete only one element, may corrupt the heap, or worse...
delete pBuffer;
相反,您应该在删除数据数组时执行此操作:
//This deletes all items in the array
delete[] pBuffer;
<> >代码>新< /COD>关键字是C++的方式,它将确保您的类型具有其<强>构造函数> < /St>>。new
关键字的类型安全性也更高,而malloc
则根本不安全
我认为使用malloc
会有好处的唯一方法是,如果您需要更改数据缓冲区的大小。new
关键字没有类似于realloc
的方式。realloc
函数可能能够更有效地扩展内存块的大小
值得一提的是,您不能将new
/free
和malloc
/删除混用
注:此问题的部分答案无效
int* p_scalar = new int(5); // Does not create 5 elements, but initializes to 5
int* p_array = new int[5]; // Creates 5 elements
使用malloc
和free
仅用于分配将由以c为中心的库和API管理的内存。对于你所控制的所有事物,使用<强> >代码> <强> >和> < > > >删除> /代码> <强>(以及<强> >代码> [/C>>/Stutial-变体]。<如果你有C代码要转到C++,你可以在其中留下任何MARROCK()调用。对于任何新的C++代码,我建议使用新的替代。总是在C++中使用新的。如果需要非类型化内存块,可以直接使用operator new:
void *p = operator new(size);
...
operator delete(p);
从:
[16.4]为什么我应该使用新的而不是
值得信赖的老马洛克()
常见问题解答:新建/删除呼叫
构造函数/析构函数;新型
安全,马洛克不是;新的可以是
被类重写的
FQA:您提到的新产品的优点
常见问题不是美德,因为
构造函数、析构函数和
运算符重载是垃圾(请参阅
当你没有垃圾时会发生什么
收集?),以及类型安全
这个问题在这里非常小(正常情况下)
您必须将
malloc指向指向的右指针类型
将其指定给类型化指针变量,
这可能很烦人,但远不是
“不安全”)
哦,还有使用可靠的老马洛克
使平等地使用
值得信赖的老公司。可惜我们
没有一个闪亮的新操作员更新或什么的
尽管如此,新的还不足以让人失望
证明偏离共同标准是正当的
一种语言中使用的风格,甚至
当语言是C++时。在里面
特别是具有非平凡属性的类
构造函数将在致命错误中行为不端
如果您只是简单地对对象进行malloc处理,则可以使用多种方法。
那么为什么不在整个过程中使用新的呢
密码?人们很少让操作员超负荷工作
新的,所以它可能不会进入你的
太多了。如果他们真的超负荷了呢
新的,你可以随时要求他们停止
对不起,我就是忍不住。:) new
和delete
操作符可以对类和结构进行操作,而malloc
和free
只能对需要强制转换的内存块进行操作
使用
new/delete
将有助于改进代码,因为您不需要将分配的内存强制转换为所需的数据结构。从较低的角度来看,新的内存将在内存之前初始化所有内存,而MALOC将保持内存的原始内容。 < P>简短的答案是:不要在C++中使用<代码> MalOC ,没有这样做的充分理由。代码> MaloC/<代码>在使用C++时有许多不足之处,定义< <代码>新< /C> >克服。
新的C++代码缺陷
malloc
在任何意义上都不是类型安全的。在C++中,您需要从#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
}
将使f2
的malloc
也变差,没有任何明显的诊断。这里的示例很简单,但可能会在更远的地方意外引入非POD性(例如,在基类中,通过添加非POD成员)。如果您有C++11/boost,您可以使用is_pod
检查此假设是否正确,如果不正确,则产生错误:
#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)));
}
malloc
不能很好地使用构造函数,它只考虑分配一块字节。我们可以进一步扩展我们的safe\u foo\u malloc
,以使用placementnew
:
#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();
}
现在,尽管在修复我们目前发现的所有问题时,我们实际上已经重新设计了默认的新的操作符。如果您要使用malloc
和placementnew
,那么您最好先使用new
malloc
和new
之间有一个很大的区别<代码>malloc
分配内存。这对于C来说很好,因为在C中,一块内存是一个对象
C++中,如果你不处理POD类型(类似于C类型)
#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;
}
#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();
}
#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)...);
}
};
non_pod_type* p = (non_pod_type*) malloc(sizeof *p);
non_pod_type* p = new non_pod_type();
pod_type* p = (pod_type*) malloc(sizeof *p);
std::cout << p->foo;
pod_type* p = new pod_type();
std::cout << p->foo; // prints 0
std::unique_ptr<T> p = std::unique_ptr<T>(new T()); // this won't leak
class B {
private:
B *ptr;
int x;
public:
B(int n) {
cout<<"B: ctr"<<endl;
//ptr = new B; //keep calling ctr, result is segmentation fault
ptr = (B *)malloc(sizeof(B));
x = n;
ptr->x = n + 10;
}
~B() {
//delete ptr;
free(ptr);
cout<<"B: dtr"<<endl;
}
};
struct test_s {
int some_strange_name = 1;
int &easy = some_strange_name;
}
std::vector<int> *createVector(); // Bad
std::vector<int> createVector(); // Good
auto v = new std::vector<int>(); // Bad
auto result = calculate(/*optional output = */ v);
auto v = std::vector<int>(); // Good
auto result = calculate(/*optional output = */ &v);
auto instance = std::make_unique<Class>(/*args*/); // C++14
auto instance = std::unique_ptr<Class>(new Class(/*args*/)); // C++11
auto instance = std::make_unique<Class[]>(42); // C++14
auto instance = std::unique_ptr<Class[]>(new Class[](42)); // C++11
auto optInstance = std::optional<Class>{};
if (condition)
optInstance = Class{};
auto vector = std::vector<std::unique_ptr<Interface>>{};
auto instance = std::make_unique<Class>();
vector.push_back(std::move(instance)); // std::move -> transfer (most of the time)
auto instance = std::make_unique<Class>();
legacyFunction(instance.release()); // Ownership being transferred
auto instance = std::unique_ptr<Class>{legacyFunction()}; // Ownership being captured in unique_ptr
auto instance = new Class(); // Allocate memory
delete instance; // Deallocate
auto instances = new Class[42](); // Allocate memory
delete[] instances; // Deallocate
auto instanceBlob = std::malloc(sizeof(Class)); // Allocate memory
auto instance = new(instanceBlob)Class{}; // Initialize via constructor
instance.~Class(); // Destroy via destructor
std::free(instanceBlob); // Deallocate the memory