malloc returns void pointer to the starting memory address of the allocated memory upon successful memory allocation. Depending upon compiler you might also have to type-cast it. However, for portability it is always good idea to type cast it. One thing which I see most people not following when using malloc is “error-check”. It is really important to check for failed memory allocations when using malloc.

/* BAD Practice */

int  *iptr;
iptr = (int *) malloc (sizeof(int)) ;

Imagine a scenario when you used malloc and memory is not allocated. Now, since you did not checked for
error condition you don’t know that memory has not actually been allocated. You will fearlessly use the pointer
later in your code, BUT WHAT HAPPENS WHEN YOU RUN IT? Oh, did I hear SEGMENTATION FAULT? It’s because when malloc fails it returns NULL. And we all know what happens when we dereference NULL pointer. We get Segmentation fault. So to avoid this, better way is:

/* Good Practice */

int *iptr = NULL ; /* always initialize pointer  */
iptr  = (int *) malloc (sizeof(int)) ;

if (iptr == NULL) {
      printf("error: memory allocation failed \n");
      exit(-1) ;
}

Now your code will exit in case of memory allocation failure.

Similarly, when using “new” in C++, in case of memory failure, exception is thrown. So you should enclose the code inside try-catch block.

// Using new and delete

int  *iptr = NULL ;

try {

     ptr  = new int ;

} catch (bad_alloc &memoryAllocationFailed) {

     cerr<<"error: memory allocation failed \n";
     cerr<<memoryAllocationFailed.what()       ;
     exit(-1) ;
}

Again, your code will exit in case of memory allocation failure. Notice the use of cerr in the code above instead of cout. cerr prints on stderr (file descriptor 2), which prints the error messages as soon as possible. Unlike cout, cerr does not buffer anything. Therefore, it is very useful while printing error messages.

In C++, the main benefit of using new over malloc is what most books don’t tell. Let me show you an example of the problematic code first.

Consider this:

// Problematic code

class base {
    public:
  	base() {
	    cout<<"Base constructor \n";
	}
      ~base() {
	    cout<<"Base destructor \n";
	}

} ;

int main(int argc, char **argv) {

	    base *bptr = NULL ;
	    bptr = (base *) malloc (sizeof(base)) ;
	    if (bptr == NULL) {
		printf("error: memory allocation failed \n");
		exit(-1) ;
	    }

	    free(bptr) ;
	    bptr = NULL;

	    return 0;
}

Now guess the output. Did I hear you say, the output will be
Base constructor
Base destructor

Well, bad news, above output is wrong. YES. When you allocate a memory using malloc, it just, well allocates memory. It does not call the class’s constructor as you might expect it to be. Now you might think, why do we care whether the constructor is called or not. It’s because, if you have some pointer as data member for which you allocate memory in constructor and use it later, and since your constructor was never called, the next time you derefence that pointer you will get segmentation fault. Similarly, when you try to free memory using “free”, it will not call destructor.

So to deal with this, we do things C++ way, we use new to allocate memory and delete to free the allocated memory. new will call constructor and delete will call the destructor.

// code with new 

try {

    bptr = new base; // calls constructor

} catch (bad_alloc &memoryAllocationFailed) {
    cerr<<" error: memory allocation failed \n";
    cerr<<memoryAllocationFailed.what() ;
    exit(-1) ;
}

    delete bptr ;
    bptr = NULL ;

Now output will be:
Base constructor
Base destructor

Also, for the above mentioned reasons, you should never mix new with free or malloc with delete.

Hope this article will help some of you !

Sphere: Related Content

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.