To new is C++; To malloc is C; To mix them is sin (混淆C++中的new和C中的malloc是一种犯罪)

来源:互联网 发布:淘宝如何延迟确认收货 编辑:程序博客网 时间:2024/06/05 02:43

Introduction
One of the most common questions that get asked during interviews for C++ programmers is to explain the differences between using malloc and using new. It’s also a fairly common question in some of newsgroups and C++ forums.
(在C++程序员的面试中,最常见的问题就是使用malloc和new的区别。在小组讨论和C++论坛中,两者之间的区别同样是相当普遍的话题。)

Constructors and Destructors
When you new an object, space for the object is not only allocated but the object’s constructor is called. And similarly when you delete an object, the object’s destructor is called before the memory is released. If you use malloc and free, the destructor and constructor do not get called respectively and obviously, this simply won’t do in C++ except in certain very rare situations where you have classes without any specific destructor/constructors.
(当你new一个对象的时候,不仅仅为对象分配了空间,同事调用了对象的构造函数。同样的,当你delete一个对象时,在内存释放之前会调用对象的析构函数。如果你使用malloc和free,构造函数和析构函数都不会被调用。对于没有构造函数和析构函数的特殊情况下,这个小例子不会起作用。)
It’s very easy to test this out by using the following test class.
(通过下面的test类,很容易得到结论)

class Test{    public:    Test()    {        cout << "Test : ctor\r\n";    }    ~Test()    {        cout << "Test : dtor\r\n";    }    void Hello()    {        cout << "Test : Hello World\r\n";    }};

Create, use and delete the object using new/delete as well as using malloc/free :-
(使用new/delete、malloc/free来创建、使用、删除对象)

int _tmain(int argc, _TCHAR* argv[]){    cout << "1\r\n";    Test* t1 = new Test();    t1->Hello();    delete t1;    cout << "2\r\n";    Test* t2 = (Test*) malloc(sizeof Test);    t2->Hello();    free(t2);    return 0;}

You’ll see the following output:-
(你会看到以下输出)
1
Test : ctor
Test : Hello World
Test : dtor
2
Test : Hello World

As obvious from the output, malloc/free did not result in either the destructor or the constructor being called.
(从输出结果可以清楚得到,malloc/free既没有调用构造函数也没有调用析构函数。)

Choosing constructor overloads
For non-array allocations, you can actually specify the specific overload of the constructor that you wish to use as in :- T t = new T(x, y, z); For array allocations using new, the default constructor will get used. If you attempt an array allocation on an object that does not have a default constructor, you get a compiler error .
(对于非数组分配空间,你可以使用T t = new T(x, y, z)去区别重载的构造函数。对于使用new分配的数组空间,默认的构造函数将被调用。如果对于不存在默认构造函数的对象分配数组空间,将是编译错误。)
class Test2
{
public:
Test2(int y)
{
}
};
//…
Test2* t2array = new Test2[10];
For example, if you attempt to compile the above snippet, you’ll get an error
(例,如果你尝试编译以上代码片段,便会得到错误。)
Type-casting forced by malloc
Because malloc returns a void* the caller has to do a type-cast to get it to compile.
(由于malloc的返回值为void*,所以需要进行强制类型转换)
Test* t1 = new Test();
Test* t2 = (Test*) malloc(sizeof Test);

Native types
For native types new/delete and malloc/free work the same way except for the need to type-cast in the case of malloc/free. So it’s just a matter of user preference.
(对于内置的类型,除了malloc/free的强制类型转换外,new/delete和malloc/free的工作方式相同。)

//declaring native typeint* i1 = new int;delete i1;int* i2 = (int*) malloc(sizeof(int));free(i2);//declaring native type arraychar** c1 = new char*[10];delete[] c1;char** c2 = (char**) malloc(sizeof(char)*10);free(c2);

Safety tip
Always delete what you new, and free what you malloc, never mix new with free or malloc with delete.
(总要delete你所new的内容,free你所malloc的内容,千万不要混淆使用。)
No realloc alternative for new/delete
The new/delete couple not have a realloc alternative that is available when you use the malloc/free pair. realloc is pretty handy if you want to resize the length of an array or a memory block dynamically, specially since the contents of the array/block remain same up to the shorter of the old and new sizes. To see this in action, see the following code snippet :-
(new/delete的组合没有类似于realloc这样的函数。如果你想你想动态重新设置数组的长度或是内存块的长度,并且需要保留之前的内容,realloc是一个相当方便的操作。为了看看realloc如何工作的,请看下面的代码块:)

char* p = (char*)malloc(sizeof(char)*12);strcpy(p,"hello world");cout << p << "\r\n";p = (char*)realloc(p, sizeof(char)*24);strcat(p," from Nish");cout << p << "\r\n";free(p);

The output you get will be :-
hello world
hello world from Nish
As you can see from the output, the original contents were retained.
(正如你看到的,原有的内容被保存了。)

2 0
原创粉丝点击