In what cases do I use malloc and/or new?

前端 未结 19 1659
北恋
北恋 2020-11-21 17:41

I see in C++ there are multiple ways to allocate and free data and I understand that when you call malloc you should call free and when you use the

19条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-21 18:07

    There is one big difference between malloc and new. malloc allocates memory. This is fine for C, because in C, a lump of memory is an object.

    In C++, if you're not dealing with POD types (which are similar to C types) you must call a constructor on a memory location to actually have an object there. Non-POD types are very common in C++, as many C++ features make an object automatically non-POD.

    new allocates memory and creates an object on that memory location. For non-POD types this means calling a constructor.

    If you do something like this:

    non_pod_type* p = (non_pod_type*) malloc(sizeof *p);
    

    The pointer you obtain cannot be dereferenced because it does not point to an object. You'd need to call a constructor on it before you can use it (and this is done using placement new).

    If, on the other hand, you do:

    non_pod_type* p = new non_pod_type();
    

    You get a pointer that is always valid, because new created an object.

    Even for POD types, there's a significant difference between the two:

    pod_type* p = (pod_type*) malloc(sizeof *p);
    std::cout << p->foo;
    

    This piece of code would print an unspecified value, because the POD objects created by malloc are not initialised.

    With new, you could specify a constructor to call, and thus get a well defined value.

    pod_type* p = new pod_type();
    std::cout << p->foo; // prints 0
    

    If you really want it, you can use use new to obtain uninitialised POD objects. See this other answer for more information on that.

    Another difference is the behaviour upon failure. When it fails to allocate memory, malloc returns a null pointer, while new throws an exception.

    The former requires you to test every pointer returned before using it, while the later will always produce valid pointers.

    For these reasons, in C++ code you should use new, and not malloc. But even then, you should not use new "in the open", because it acquires resources you need to release later on. When you use new you should pass its result immediately into a resource managing class:

    std::unique_ptr p = std::unique_ptr(new T()); // this won't leak
    

提交回复
热议问题