Take the 2-minute tour ×

I got a comment to my answer on this thread:


In short I had code like this:

int * somefunc (void)
  int * temp = (int*) malloc (sizeof (int));
  temp[0] = 0;
  return temp;

I got this comment:

Can I just say, please don't cast the return value of malloc? It is not required and can hide errors.

I agree that the cast is not required in C. It is mandatory in C++, so I usually add them just in case I have to port the code in C++ one day.

However, I wonder how casts like this can hide errors. Any ideas?


Seems like there are very good and valid arguments on both sides. Thanks for posting, folks.

share|improve this question

12 Answers 12

up vote 17 down vote accepted

It seems fitting I post an answer, since I left the comment :P

Basically, if you forget to include stdlib.h the compiler will assume malloc returns an int. Without casting, you will get a warning. With casting you won't.

So by casting you get nothing, and run the risk of suppressing legitimate warnings.

Much is written about this, a quick google search will turn up more detailed explanations.


It has been argued that

TYPE * p;
p = (TYPE *)malloc(n*sizeof(TYPE));

makes it obvious when you accidentally don't allocate enough memory because say, you thought p was TYPe not TYPE, and thus we should cast malloc because the advantage of this method overrides the smaller cost of accidentally suppressing compiler warnings.

I would like to point out 2 things:

  1. you should write p = malloc(sizeof(*p)*n); to always ensure you malloc the right amount of space
  2. with the above approach, you need to make changes in 3 places if you ever change the type of p: once in the declaration, once in the malloc, and once in the cast.

In short, I still personally believe there is no need for casting the return value of malloc and it is certainly not best practice.

share|improve this answer
:-) haha.. you found the question. Great. –  Nils Pipenbrinck Sep 20 '08 at 17:18
That's the only problem I ever can imagine. ;) –  unexist Sep 20 '08 at 17:20
Just run your compiler with -pedantic-errors to be always on the safe side. ;) –  unexist Sep 20 '08 at 19:17
@onebyone I didn't cite anything. That would require me to use it as backup for a statement I am using. I linked it to show conflict with in the same body. My answer in no ways cites any CERT advisory –  freespace Sep 21 '08 at 15:22
As long as we're talking about sizeof, I'd say you should write that as: p = malloc(n * sizeof *p); This is shorter, and does not use the needless (in my opinion confusing and obfuscating) parenthesis around the argument. Those are only needed with type names, not with other objects. –  unwind Oct 27 '08 at 11:56

This question is tagged both for C and C++, so it has at least two answers, IMHO:


Ahem... Do whatever you want.

I believe the reason given above "If you don't include "stdlib" then you won't get a warning" is not a valid one because one should not rely on this kind of hacks to not forget to include an header.

The real reason that could make you not write the cast is that the C compiler already silently cast a void * into whatever pointer type you want, and so, doing it yourself is overkill and useless.

If you want to have type safety, you can either switch to C++ or write your own wrapper function, like:

int * malloc_Int(size_t p_iSize) /* number of ints wanted */
   return malloc(sizeof(int) * p_iSize) ;


Sometimes, even in C++, you have to make profit of the malloc/realloc/free utils. Then you'll have to cast. But you already knew that. Using static_cast<>() will be better, as always, than C-style cast.

And in C, you could override malloc (and realloc, etc.) through templates to achieve type-safety:

template <typename T>
T * myMalloc(const size_t p_iSize)
 return static_cast<T *>(malloc(sizeof(T) * p_iSize)) ;

Which would be used like:

int * p = myMalloc<int>(25) ;
free(p) ;

MyStruct * p2 = myMalloc<MyStruct>(12) ;
free(p2) ;

and the following code:

// error: cannot convert ‘int*’ to ‘short int*’ in initialization
short * p = myMalloc<int>(25) ;
free(p) ;

won't compile, so, no problemo.

All in all, in pure C++, you now have no excuse if someone finds more than one C malloc inside your code... :-)

C + C++ crossover

Sometimes, you want to produce code that will compile both in C and in C++ (for whatever reasons... Isn't it the point of the C++ extern "C" {} block?). In this case, C++ demands the cast, but C won't understand the static_cast keyword, so the solution is the C-style cast (which is still legal in C++ for exactly this kind of reasons).

Note that even with writing pure C code, compiling it with a C++ compiler will get you a lot more warnings and errors (for example attempting to use a function without declaring it first won't compile, unlike the error mentioned above).

So, to be on the safe side, write code that will compile cleanly in C++, study and correct the warnings, and then use the C compiler to produce the final binary. This means, again, write the cast, in a C-style cast.

share|improve this answer
In your 'C' para I don't think you address the argument. The cast isn't there to cast from void*. It's there to do the same thing that your function does (prevent implicit casts to anything other than the right pointer type). Adding the cast is in that respect like using your function. –  Steve Jessop Sep 22 '08 at 1:22
Of course its still debatable whether type safety is of any benefit, since one can in any case malloc(sizeof(*p)*n) and not have to care about type. –  Steve Jessop Sep 22 '08 at 1:23
Using mallocs needs telling it you're wanting an array of int (for example). So you must use sizeof, and in the end, perhaps, add the cast (in a C/C++ compatible code). The function has the slight benefit of 1 : Full static safety, 2 : Hiding some internals that should not appear in code. –  paercebal Sep 24 '08 at 17:11
About the type safety debate: The code was not destined to the "cowboy developer", though. It was destined to the developer who wanted all the possible help coming from the compiler. Encapsulating "dangerous code" is a step toward that goal, and this function is doing exactly that... :-) ... –  paercebal Sep 24 '08 at 17:15

One possible error it can introduce is if you are compiling on a 64-bit system using C (not C++).

Basically, if you forget to include stdlib.h, the default int rule will apply. Thus the compiler will happily assume that malloc has the prototype of int malloc(); On Many 64-bit systems an int is 32-bits and a pointer is 64-bits.

Uh oh, the value gets truncated and you only get the lower 32-bits of the pointer! Now if you cast the return value of malloc, this error is hidden by the cast. But if you don't you will get an error (something to the nature of "cannot convert int to T *").

This does not apply to C++ of course for 2 reasons. Firstly, it has no default int rule, secondly it requires the cast.

All in all though, you should just new in c++ code anyway :-P.

share|improve this answer
If you switch on compiler warnings, you'll know that you've forgotten to include stdlib.h because you'll get a warning about the implicit declaration of malloc (and every other function you've used from stdlib). –  Steve Jessop Sep 21 '08 at 11:42

Well, I think it's the exact opposite - always directly cast it to the needed type. Read on here!

share|improve this answer
And from the same site: securecoding.cert.org/confluence/pages/… :-) Certainly interesting arguments from both side –  freespace Sep 20 '08 at 17:26
The argument made in that article, after some thought isn't a very good one. You should simply use p = malloc(sizeof(*p)*n); to avoid the problem all together. Now you won't have to change type in 3 places: once in declaration of p, once in malloc, once in the cast. –  freespace Sep 20 '08 at 17:54
Guess if you ask two pogrammers there's always a third more pragmatic opinion somewhere. ;) –  unexist Sep 20 '08 at 18:09

The "forgot stdlib.h" argument is a straw man. Modern compilers will detect and warn of the problem (gcc -Wall).

You should always cast the result of malloc immediately. Not doing so should be considered an error, and not just because it will fail as C++. If you're targeting a machine architecture with different kinds of pointers, for example, you could wind up with a very tricky bug if you don't put in the cast.

Edit: The commentor Evan Teran is correct. My mistake was thinking that the compiler didn't have to do any work on a void pointer in any context. I freak when I think of FAR pointer bugs, so my intuition is to cast everything. Thanks Evan!

share|improve this answer
I could be wrong, but I believe that the C standard says that a data pointer may safely be cast to and from any other data pointer. Obviously function pointers are a different issue. But malloc always returns a data pointer. –  Evan Teran Sep 21 '08 at 2:01
Yes, it can be cast, but it won't be if you don't! –  jfm3 Sep 22 '08 at 12:42
I think you are mistaken. void * is implicitly converted to the appropriate pointer type upon assignment (we all know this). If it is legal and meaningful to cast from malloc's void * to T *, then the implicit conversion should yield the same result. So the "bug" you mentioned doesn't exist. –  Evan Teran Sep 22 '08 at 13:17

Actually, the only way a cast could hide an error is if you were converting from one datatype to an smaller datatype and lost data, or if you were converting pears to apples. Take the following example:

int int_array[10];
/* initialize array */
int *p = &(int_array[3]);
short *sp = (short *)p;
short my_val = *sp;

in this case the conversion to short would be dropping some data from the int. And then this case:

struct {
    /* something */
} my_struct[100];

int my_int_array[100];
/* initialize array */
struct my_struct *p = &(my_int_array[99]);

in which you'd end up pointing to the wrong kind of data, or even to invalid memory.

But in general, and if you know what you are doing, it's OK to do the casting. Even more so when you are getting memory from malloc, which happens to return a void pointer which you can't use at all unless you cast it, and most compilers will warn you if you are casting to something the lvalue (the value to the left side of the assignment) can't take anyway.

share|improve this answer
#define MALLOC_CAST(T) (T)
#define MALLOC_CAST(T)
int * p;
p = MALLOC_CAST(int *) malloc(sizeof(int) * n);

or, alternately

#define MYMALLOC(T, N) static_cast<T*>(malloc(sizeof(T) * N))
#define MYMALLOC(T, N) malloc(sizeof(T) * N)
int * p;
p = MYMALLOC(int, n);
share|improve this answer
This is a decent workaround, but still requires maintenance if the types change. I prefer, if possible, to say "Use a C compiler, not a C++ compiler" but it's personal opinion. I do want to note that the correct macro for checking if the compiler is C++ is __cplusplus, not CPLUSPLUS. –  Chris Lutz Feb 10 '10 at 18:04

People have already cited the reasons I usually trot out: the old (no longer applicable to most compilers) argument about not including stdlib.h and using sizeof *p to make sure the types and sizes always match regardless of later updating. I do want to point out one other argument against casting. It's a small one, but I think it applies.

C is fairly weakly typed. Most safe type conversions happen automatically, and most unsafe ones require a cast. Consider:

int from_f(float f)
    return *(int *)&f;

That's dangerous code. It's technically undefined behavior, though in practice it's going to do the same thing on nearly every platform you run it on. And the cast helps tell you "This code is a terrible hack."



I see a cast, and I wonder, "Why is this necessary? Where is the hack?" It raises hairs on my neck that there's something evil going on, when in fact the code is completely harmless.

As long as we're using C, casts (especially pointer casts) are a way of saying "There's something evil and easily breakable going on here." They may accomplish what you need accomplished, but they indicate to you and future maintainers that the kids aren't alright.

Using casts on every malloc diminishes the "hack" indication of pointer casting. It makes it less jarring to see things like *(int *)&f;.

Note: C and C++ are different languages. C is weakly typed, C++ is more strongly typed. The casts are necessary in C++, even though they don't indicate a hack at all, because of (in my humble opinion) the unnecessarily strong C++ type system. (Really, this particular case is the only place I think the C++ type system is "too strong," but I can't think of any place where it's "too weak," which makes it overall too strong for my tastes.)

If you're worried about C++ compatibility, don't. If you're writing C, use a C compiler. There are plenty really good ones avaliable for every platform. If, for some inane reason, you have to write C code that compiles cleanly as C++, you're not really writing C. If you need to port C to C++, you should be making lots of changes to make your C code more idiomatic C++.

If you can't do any of that, your code won't be pretty no matter what you do, so it doesn't really matter how you decide to cast at that point. I do like the idea of using templates to make a new allocator that returns the correct type, although that's basically just reinventing the new keyword.

share|improve this answer

Casting a function which returns (void *) to instead be an (int *) is harmless: you're casting one type of pointer to another.

Casting a function which returns an integer to instead be a pointer is most likely incorrect. The compiler would have flagged it had you not explicitly cast it.

share|improve this answer

One possible error could (depending on this is whether what you really want or not) be mallocing with one size scale, and assigning to a pointer of a different type. E.g.,

int *temp = (int *)malloc(sizeof(double));

There may be cases where you want to do this, but I suspect that they are rare.

share|improve this answer

I think you should put the cast in. Consider that there are three locations for types:

T1 *p;
p = (T2*) malloc(sizeof(T3));

The two lines of code might be widely separated. Therefore it's good that the compiler will enforce that T1 == T2. It is easier to visually verify that T2 == T3.

If you miss out the T2 cast, then you have to hope that T1 == T3.

On the other hand you have the missing stdlib.h argument - but I think it's less likely to be a problem.

share|improve this answer
You can eliminate two of those three type locations and still be safe if the types change: T *p; p = malloc(sizeof *p); No cast, no possibility of type or size mismatches, no errors. –  Chris Lutz Feb 10 '10 at 18:09

On the other hand, if you ever need to port the code to C++, it is much better to use the 'new' operator.

share|improve this answer
What? But he's writing in C, he cannot use 'new'. –  Mladen Janković Sep 20 '08 at 17:23
That's the point - it shouldn't be written for C & C++, it should be the best it can for C, and then completely changed for C++. –  Douglas Leeder Sep 20 '08 at 17:31
disagree There is no need to rewrite perfectly fine C-code just to link it with a c++ module. That just raises the risk of introducing new bugs and gives no added value. –  Nils Pipenbrinck Sep 20 '08 at 18:48
@Nils - Yes there is. What if your application overrides new and delete to use a custom memory manager? Linked-in C code that calls malloc and free will still use the built-in heap allocator, which may be slower and/or not do whatever task you require your memory manager to do. You won't be able to track the memory management of your C components. If possible, you should rewrite for C++ when porting to C++. Sometimes this is unnecessary, but sometimes it is quite necessary. –  Chris Lutz Feb 10 '10 at 18:07

Your Answer


