我看到在c++中有多种方法来分配和释放数据,我明白,当你调用malloc时你应该叫自由,当你使用新的操作符应与删除和对它是错误的把两个调用free()(例如,创建新的操作符),但是我不清楚我应该使用malloc / free,当我在现实世界中应该使用新的/删除程序。
如果你是c++专家,请告诉我你在这方面遵循的任何经验法则或惯例。
我看到在c++中有多种方法来分配和释放数据,我明白,当你调用malloc时你应该叫自由,当你使用新的操作符应与删除和对它是错误的把两个调用free()(例如,创建新的操作符),但是我不清楚我应该使用malloc / free,当我在现实世界中应该使用新的/删除程序。
如果你是c++专家,请告诉我你在这方面遵循的任何经验法则或惯例。
当前回答
来自c++ FQA Lite:
[16.4] Why should I use new instead of trustworthy old malloc()? FAQ: new/delete call the constructor/destructor; new is type safe, malloc is not; new can be overridden by a class. FQA: The virtues of new mentioned by the FAQ are not virtues, because constructors, destructors, and operator overloading are garbage (see what happens when you have no garbage collection?), and the type safety issue is really tiny here (normally you have to cast the void* returned by malloc to the right pointer type to assign it to a typed pointer variable, which may be annoying, but far from "unsafe"). Oh, and using trustworthy old malloc makes it possible to use the equally trustworthy & old realloc. Too bad we don't have a shiny new operator renew or something. Still, new is not bad enough to justify a deviation from the common style used throughout a language, even when the language is C++. In particular, classes with non-trivial constructors will misbehave in fatal ways if you simply malloc the objects. So why not use new throughout the code? People rarely overload operator new, so it probably won't get in your way too much. And if they do overload new, you can always ask them to stop.
对不起,我就是忍不住。:)
其他回答
malloc()在C语言中用于动态分配内存 而在c++中,同样的工作由new()完成。 所以你不能混合两种语言的编码习惯。 如果你问calloc和malloc()之间的差异,那就好了
在下面的场景中,我们不能使用new,因为它调用构造函数。
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;
}
};
除非被迫使用C,否则永远不要使用malloc。总是使用new。
如果你需要大量的数据,可以这样做:
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;
new关键字是c++实现它的方式,它将确保你的类型的构造函数被调用。new关键字也更加类型安全,而malloc根本不是类型安全的。
我认为使用malloc有益的唯一方式是需要改变数据缓冲区的大小。new关键字没有类似realloc的方式。realloc函数可能能够更有效地扩展内存块的大小。
值得一提的是,你不能将new/free和malloc/delete混合使用。
注:本题部分答案无效。
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和new有一个很大的区别。Malloc分配内存。这对于C语言来说很好,因为在C语言中,一块内存就是一个对象。
在c++中,如果你不处理POD类型(类似于C类型),你必须在内存位置上调用构造函数来实际拥有一个对象。非pod类型在c++中非常常见,因为许多c++特性使对象自动变为非pod类型。
New分配内存并在该内存位置上创建一个对象。对于非pod类型,这意味着调用构造函数。
如果你这样做:
non_pod_type* p = (non_pod_type*) malloc(sizeof *p);
您获得的指针不能被解引用,因为它不指向对象。在使用它之前,您需要调用它的构造函数(这是使用placement new完成的)。
另一方面,如果你有:
non_pod_type* p = new non_pod_type();
你得到一个总是有效的指针,因为new创建了一个对象。
即使是POD类型,两者之间也有显著差异:
pod_type* p = (pod_type*) malloc(sizeof *p);
std::cout << p->foo;
这段代码将打印一个未指定的值,因为由malloc创建的POD对象没有初始化。
使用new,可以指定要调用的构造函数,从而获得定义良好的值。
pod_type* p = new pod_type();
std::cout << p->foo; // prints 0
如果你真的想要它,你可以使用use new来获得未初始化的POD对象。有关更多信息,请参阅另一个答案。
另一个区别是失败时的行为。当它分配内存失败时,malloc返回一个空指针,而new则抛出异常。
前者要求您在使用它之前测试返回的每个指针,而后者将始终产生有效的指针。
基于这些原因,在c++代码中应该使用new,而不是malloc。但即便如此,你也不应该“公开”使用新的内容,因为它会占用你以后需要发布的资源。当你使用new时,你应该立即将它的结果传递给一个资源管理类:
std::unique_ptr<T> p = std::unique_ptr<T>(new T()); // this won't leak
我以前玩过很少的计算机图形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);
可能会出现一些错误,因为数组的大小太小。 但这是另一个故事,并不是因为使用了演员阵容。
致以亲切的问候,艾德里安·布里纳斯