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

前端 未结 19 1651
北恋
北恋 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条回答
  • 2020-11-21 17:54

    malloc() is used to dynamically assign memory in C while the same work is done by new() in c++. So you cannot mix coding conventions of 2 languages. It would be good if you asked for difference between calloc and malloc()

    0 讨论(0)
  • 2020-11-21 17:57

    Dynamic allocation is only required when the life-time of the object should be different than the scope it gets created in (This holds as well for making the scope smaller as larger) and you have a specific reason where storing it by value doesn't work.

    For example:

     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);
    

    From C++11 on, we have std::unique_ptr for dealing with allocated memory, which contains the ownership of the allocated memory. std::shared_ptr was created for when you have to share ownership. (you'll need this less than you would expect in a good program)

    Creating an instance becomes really easy:

    auto instance = std::make_unique<Class>(/*args*/); // C++14
    auto instance = std::make_unique<Class>(new Class(/*args*/)); // C++11
    auto instance = std::make_unique<Class[]>(42); // C++14
    auto instance = std::make_unique<Class[]>(new Class[](42)); // C++11
    

    C++17 also adds std::optional which can prevent you from requiring memory allocations

    auto optInstance = std::optional<Class>{};
    if (condition)
        optInstance = Class{};
    

    As soon as 'instance' goes out of scope, the memory gets cleaned up. Transferring ownership is also easy:

     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)
    

    So when do you still need new? Almost never from C++11 on. Most of the you use std::make_unique until you get to a point where you hit an API that transfers ownership via raw pointers.

     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
    

    In C++98/03, you have to do manual memory management. If you are in this case, try upgrading to a more recent version of the standard. If you are stuck:

     auto instance = new Class(); // Allocate memory
     delete instance;             // Deallocate
     auto instances = new Class[42](); // Allocate memory
     delete[] instances;               // Deallocate
    

    Make sure that you track the ownership correctly to not have any memory leaks! Move semantics don't work yet either.

    So, when do we need malloc in C++? The only valid reason would be to allocate memory and initialize it later via placement new.

     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
    

    Even though, the above is valid, this can be done via a new-operator as well. std::vector is a good example for this.

    Finally, we still have the elephant in the room: C. If you have to work with a C-library where memory gets allocated in the C++ code and freed in the C code (or the other way around), you are forced to use malloc/free.

    If you are in this case, forget about virtual functions, member functions, classes ... Only structs with PODs in it are allowed.

    Some exceptions to the rules:

    • You are writing a standard library with advanced data structures where malloc is appropriate
    • You have to allocate big amounts of memory (In memory copy of a 10GB file?)
    • You have tooling preventing you to use certain constructs
    • You need to store an incomplete type
    0 讨论(0)
  • 2020-11-21 17:59

    From a lower perspective, new will initialize all the memory before giving the memory whereas malloc will keep the original content of the memory.

    0 讨论(0)
  • 2020-11-21 18:00

    If you have C code you want to port over to C++, you might leave any malloc() calls in it. For any new C++ code, I'd recommend using new instead.

    0 讨论(0)
  • 2020-11-21 18:01

    new will initialise the default values of the struct and correctly links the references in it to itself.

    E.g.

    struct test_s {
        int some_strange_name = 1;
        int &easy = some_strange_name;
    }
    

    So new struct test_s will return an initialised structure with a working reference, while the malloc'ed version has no default values and the intern references aren't initialised.

    0 讨论(0)
  • 2020-11-21 18:02

    new vs malloc()

    1) new is an operator, while malloc() is a function.

    2) new calls constructors, while malloc() does not.

    3) new returns exact data type, while malloc() returns void *.

    4) new never returns a NULL (will throw on failure) while malloc() returns NULL

    5) Reallocation of memory not handled by new while malloc() can

    0 讨论(0)
提交回复
热议问题