How To Cast The Result Of malloc

Updated:

A question that often arises when allocating a new block of memory in C is: should I cast the result of malloc or not?

Let’s take an example.

Allocating an array

We want to dynamically allocate an array of floats called samples. So we need to declare a pointer variable that will point to the base address of this array.

With an explicit cast we would write:

float *samples = (float *) malloc(sizeof(*samples) * number_of_samples);

Without the explicit cast operation we would write:

float *samples = malloc(sizeof(*samples) * number_of_samples);

Later we will discuss the content of the argument of malloc(), but for now let us ask ourselves: which of the two versions should I use?

Let’s start by saying that both versions are correct in C, but most experienced programmers prefer the method without casting, the second one.

A different case is whether you have to compile a piece of C code as C++, in which case the explicit cast operation is mandatory and there is no room for discussion.

The point is that in C malloc returns a void pointer, and a void pointer is automatically and safely promoted to any other pointer type. So it might seem like it’s just superfluous. In reality, we can think more deeply and analyze the two cases to understand why the second is the most adopted.

So, what are the advantages and disadvantages in C for casting the result of malloc or not?

To cast or not to cast

Why you might want to cast:

  • To make your code more portable between C and C++.
  • To help the developer identify inconsistencies in type sizing (so we are talking about the argument of malloc). This can especially help when the pointer is declared far from the malloc call.
  • To nudge the developer for extra verification in mind.

Why you don’t want to cast:

  • The cast from a void pointer is redundant, unnecessary.
  • It produces repetitions, which is generally not a good thing in coding.
  • When you cast, you may hide an error if you forgot to include stdlib.h, in which the prototype for malloc is found. When the compiler cannot find the prototype of malloc, as for the C standard, it assumes that malloc returns an int. This is an implicit function declaration. Now, if a function returns an int and we try to store that int in a pointer we get a warning from the compiler. Instead with the cast this warning is not produced, thus masking a bug.
  • If you change the the type of the pointer in its declaration you also need to change all the explicit casts where malloc is called. Obviously, there’s no need if you don’t cast.

The argument of malloc

A final thought on the argument that we pass to malloc().

float *samples = malloc(sizeof(*samples) * number_of_samples);

We need to calculate the size of memory needed to store all the samples, so we multiply the number of samples by the size in memory of each sample. And so far nothing strange.

There are actually two details that can be overlooked.

  • The size of each sample is coded as sizeof(*samples) and not as sizeof(float). Using sizeof(float) the code needlessly repeats the type information (float) and this can cause errors. It’s better to de-reference the pointer used to store the return value of malloc, so we’ll use *samples. This way this size is locked in the samples declaration, so we satisfy the good habit of “only a place to make changes”.

  • The order of the multiplication operands should not be overlooked either. While moving number_of_samples to the front may increase your attention on this variable, keeping the sizeof first ensures multiplication is done with at least size_t math. In fact, this multiplication may overflow if we put number_of_samples first and its type was smaller than size_t. So, it’s safer to put sizeof first.