菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
128
0

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

原创
05/13 14:22
阅读数 15980

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 type
int* i1 = new int;
delete i1;
int* i2 = (int*) malloc(sizeof(int));
free(i2);
//declaring native type array
char** 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.
(正如你看到的,原有的内容被保存了。)

发表评论

0/200
128 点赞
0 评论
收藏
为你推荐 换一批