CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1
  1. #1
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    C++ Memory Management : What is the difference between malloc/free and new/delete?

    Q: What is the difference between malloc/free and new/delete?

    A : 'malloc()' is a function inherited in C++ from C. It is defined in '<stdlib.h>' in C and '<cstdlib>' in C++. Its main purpose is to request the OS (free store) for a bunch of memory bytes for you. You would make a call to 'malloc()' and the request goes to the operating system that allocates the requested amount of contiguous raw bytes if possible. I say "if possible" because under certain circumstances (like lack of memory), the request may not be successfully acknowledged. Let's take a look at the prototype:
    Code:
    void* malloc(size_t size);
    On success, you would get a pointer to the first byte of allocated memory. On failure, 'NULL' would be returned. 'size' is an input variable that corresponds to the requested number of bytes. Wait! Don't stop here, read further else don't blame me for the problems in your code using 'malloc()'. Here are some relevant links:


    'free()' is a function inherited in C++ from C. It is defined in '<stdlib.h>' in C and '<cstdlib>' in C++. Its main purpose it to free the memory acquired explicitly by a call to 'malloc()'. That means, if you make a request for some bytes using 'malloc()' then when you are done with using those bytes you must return them back to whom you took it from. Every 'malloc()' call must be followed by a call to 'free()' else you get into a situation called a memory leak. That piece of malloc-ed memory remains unusable to your program as well as the OS, until your program ends. Of course, that is not good. Let's take a look at the prototype:
    Code:
    void free(void* memblock);
    Here, 'memblock' is the same pointer that you would get from a call to 'malloc()'. It is also a good practice to set that pointer to 'NULL' after the 'free()' call and always have the 'free()' call surrounded by a check on the validness of the pointer. Calling 'free()' on the same pointer twice or a 'NULL ' pointer or any other pointer (not acquired by a 'malloc()' call) leads to an undefined behaviour of the program (including but not limited to a crash). Here you can read more about free:
    • free @ cplusplus.com
    • free @ msdn.microsoft.com


    'new' is a C++ operator. The task that you will use this for is still request for dynamic allocation of one object or multiple objects. On success, it returns a suitably typed pointer and on failure it would throw an exception ('std::bad_alloc'). There is a nothrow version of 'new' as well. C++ objects are different. They are constructed in basically two steps:
    • first, allocation of requried amount of bytes and
    • second, a successful call of the constructor.

    Take a look at the code below:
    Code:
    class A 
    {
      /*some members and a public constructor taking no arguments*/
    
    public:
      A() { /* ... */ }
    };
    
    int main()
    {
       A* ptr = new A();   // (1)
       A* ptrToArrayOfAObjects = new A[10];   // (2)
    }
    At statement labeled (1), we use 'new' to allocate memory for a single 'A' object and then a call to the constructor of 'A' happens. To verify, put a 'cout' statement in the constructor and see for yourself. At statement labeled (2), we use array form of new to construct 10 'A' objects. That is, allocate for 10 objects and call the constructor for each. That is what 'new' or 'new[]' does. This array version of 'new' requires a default constructor (i.e. a constructor without parameters) or a contructor with default values for all the parameters (that evaluates to a default constructor). You can read more here: C++ : new operator @ msdn.microsoft.com

    'delete' It is the counter-part of 'new' and also a C++ operator. The task that you will use this for is to free up memory acquired by a call to 'new'. For the allocations shown in the above code you will need to do the following:
    Code:
    class A 
    {
      /*some members and a public constructor taking no arguments*/
    public:
      A() { /* ... */ }
      ~A() { /* ... */ }
    };
    
    int main()
    {
      A* ptr = new A();   // (1)
      A* ptrToArrayOfAObjects = new A[10];   // (2)
      delete ptr;
      delete [] ptrToArrayOfAObjects;
    }
    'delete' does two things as well:
    • it first calls the destructor of the object and then
    • makes the deallocations.

    Calling 'delete' on the same pointer twice or some different pointer (not acquired by a 'new' call) leads to undefined behaviour. But calling 'delete' on 'NULL' pointers is safe and hence it is a good practice to set the pointers to 'NULL' after a call to 'delete', but unlike 'free()' no checks here for validness is required. You can read more here: C++ : delete operator @ msdn.microsoft.com

    You have to make sure you use the correct match of 'new' and 'delete'. According to the C++ standard:
    • if you allocate with 'new' you release with 'delete'
    • if you allocate with 'new[]' you release with 'delete[]'

    Otherwise the behaviour is undefined.

    By now, you should be able to understand the differences between 'malloc()'/'free()' and 'new'/'delete' but still I will put up some points to make it really explicit so as to kill any scope of confusions.
    • 'malloc()' allocates a bunch of bytes while 'new' does the allocation as well as has the responsibility of calling the constructor.
    • 'malloc' returns 'NULL' on failure while 'new' throws an exception object of type 'std::bad_alloc'. (There exists a nothrow version of 'new', though)
    • 'malloc' is the C way of dealing with the free store while 'new' is the C++ way.
    • Every call to 'malloc()' should be followed by a call to 'free()' while every call to 'new' should be followed by a call to 'delete'.
    • 'free()' deallocates all bytes allocated by a prior 'malloc()' call (using the same pointer) while 'delete' makes a call to the destructor and then goes on with the deallocation.
    • There are array forms of 'new' and 'delete' while 'malloc()' and 'free()' do not (as the request is for a specific size of raw memory in bytes).
    • 'free()' on 'NULL' pointers is not safe while 'delete' is.


    Notes:
    • Do not mix the allocation and deallocation routines i.e. do not use 'malloc()' with 'delete' or 'new' with 'free()'.
    • There are circumstances when you can use 'malloc()'/'free()' for C++ objects (POD as well as non-POD). For example, when managing a memory pool. There you explicitly call the constructor using 'placement new' operator syntax and the destructor. Let's keep that for later.



    References:
    • Item 3 : Prefer new and delete to malloc and free - from Effective C++ by Scott Meyers.
    • Free-store management @ C++ FAQ Lite



    Last edited by Andreas Masur; November 4th, 2006 at 01:36 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured