Question
In C, I have seen advice that the result of malloc should usually not be cast. For example, this code is recommended:
int *sieve = malloc(sizeof(*sieve) * length);
instead of:
int *sieve = (int *)malloc(sizeof(*sieve) * length);
Why is it generally recommended not to cast the return value of malloc in C?
Short Answer
By the end of this page, you will understand what malloc returns in C, why an explicit cast is usually unnecessary, and how avoiding the cast can actually make your code safer. You will also see the difference between C and C++, learn common allocation patterns, and practice writing correct dynamic memory code.
Concept
In C, malloc returns a value of type void *. A void * is a generic pointer type that can be automatically converted to any object pointer type in C.
That means this is valid C:
int *numbers = malloc(10 * sizeof *numbers);
No cast is needed because the language already allows converting void * to int * automatically.
Why avoiding the cast is recommended
1. It is unnecessary in C
Since the conversion happens automatically, the cast adds no benefit.
2. It can hide missing headers
If you forget to include:
#include <stdlib.h>
then the compiler may not see the correct declaration of malloc. In older C or permissive compiler modes, it may assume malloc returns an int instead of void *. If you cast that incorrect result, the code may compile without clearly warning you, even though it is wrong.
Mental Model
Think of malloc as a storage desk that hands you a generic claim ticket.
mallocgives you avoid *, which means “here is a block of memory”- In C, if you assign that ticket to an
int *, the language already knows how to treat it as “memory for integers” - Adding a cast is like writing extra instructions on a ticket that already works
Worse, if the storage desk gives you the wrong kind of ticket because you forgot the proper form (#include <stdlib.h>), the cast can make the mistake less obvious.
So in C:
- no cast = cleaner code and better error detection
- cast = unnecessary and sometimes harmful
Syntax and Examples
Core syntax
#include <stdlib.h>
int *arr = malloc(count * sizeof *arr);
if (arr == NULL) {
/* handle allocation failure */
}
Beginner-friendly example
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int length = 5;
int *numbers = malloc(length * sizeof *numbers);
if (numbers == NULL) {
return 1;
}
for (int i = 0; i < length; i++) {
numbers[i] = i * 10;
}
for (int i = 0; i < length; i++) {
printf("%d\n", numbers[i]);
}
free(numbers);
return 0;
}
Step by Step Execution
Consider this example:
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int length = 3;
int *sieve = malloc(sizeof *sieve * length);
if (sieve == NULL) {
return 1;
}
sieve[0] = 10;
sieve[1] = 20;
sieve[2] = 30;
printf("%d %d %d\n", sieve[0], sieve[1], sieve[2]);
free(sieve);
return 0;
}
Step by step
1. length is set to 3
int length = 3;
We want space for 3 integers.
2. malloc is called
Real World Use Cases
Dynamic allocation with malloc is used when the amount of memory needed is only known while the program is running.
Common use cases
- Reading file data when file size is not fixed
- Building arrays from user input
- Creating data structures such as linked lists, stacks, queues, and trees
- Allocating image or audio buffers
- Handling network packets or parsed records
Example scenarios
User-sized array
A program asks the user how many numbers to store.
int count;
scanf("%d", &count);
int *values = malloc(count * sizeof *values);
Buffer for file contents
A program reads a file and allocates a buffer based on its size.
char *buffer = malloc(file_size + 1);
Node creation in a linked list
struct Node *node = malloc(sizeof *node);
In all of these, the same idea applies: in C, you normally do not cast the result of .
Real Codebase Usage
In real C codebases, developers usually combine malloc with a few common patterns.
1. Allocate using the target variable type
struct Item *item = malloc(sizeof *item);
This avoids repeating the type name and reduces mismatches.
2. Check for NULL
char *buf = malloc(size);
if (buf == NULL) {
return -1;
}
This is a common guard clause.
3. Use early returns on failure
int *data = malloc(n * sizeof *data);
if (data == NULL) {
return NULL;
}
4. Free memory in cleanup paths
char *a = malloc(100);
char *b = ();
(a == || b == ) {
(a);
(b);
;
}
Common Mistakes
1. Forgetting to include <stdlib.h>
Broken code:
int *p = malloc(sizeof *p);
If <stdlib.h> is missing, malloc may not be declared correctly.
Correct code:
#include <stdlib.h>
int *p = malloc(sizeof *p);
2. Casting malloc and hiding the missing declaration problem
Broken style in C:
int *p = (int *)malloc(sizeof *p);
Why it is risky:
- the cast is unnecessary
- it can reduce the chance that you notice
mallocwas not declared properly
Better:
int *p = malloc( *p);
Comparisons
| Topic | C | C++ |
|---|---|---|
malloc return type | void * | void * |
Automatic conversion from void * to int * | Yes | No |
Cast needed for malloc result | Usually no | Yes, if using malloc |
| Preferred allocation style | malloc/free | Usually new/delete or containers |
sizeof(int) vs sizeof *ptr
Cheat Sheet
Quick rules
- In C, do not usually cast the result of
malloc - Always include:
#include <stdlib.h>
- Prefer:
Type *ptr = malloc(count * sizeof *ptr);
- Check for allocation failure:
if (ptr == NULL) {
/* handle error */
}
- Free allocated memory when done:
free(ptr);
Common patterns
Single object
struct Node *node = malloc(sizeof *node);
Array
int *arr = (n * *arr);
FAQ
Why does malloc return void *?
Because malloc allocates raw memory without knowing what type you want to store there. void * is a generic pointer type for that purpose.
Is casting malloc ever required in C?
Normally, no. Standard C allows automatic conversion from void * to other object pointer types.
Why can casting malloc be dangerous?
It can hide the fact that <stdlib.h> was not included, making it easier to miss a bad malloc declaration.
Should I use sizeof(int) or sizeof *ptr?
sizeof *ptr is often better because it stays correct if the pointer type changes later.
Does this advice also apply to calloc and realloc?
Yes. In C, those functions also return void *, so explicit casts are usually unnecessary.
What about C++?
Mini Project
Description
Build a small C program that creates a dynamic integer array at runtime, fills it with values, prints them, and then frees the memory. This project demonstrates the correct malloc style in C: no cast, correct sizeof usage, NULL checking, and proper cleanup.
Goal
Create and use a dynamically allocated integer array safely and idiomatically in C.
Requirements
- Ask the user how many integers to store.
- Allocate memory for that many integers using
mallocwithout casting. - Fill the array with simple values such as squares or multiples.
- Print all stored values.
- Free the allocated memory before the program exits.
Keep learning
Related questions
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.
Definition vs Declaration in C and C++: What’s the Difference?
Learn the difference between declarations and definitions in C and C++ with simple examples, common mistakes, and practical usage.
Difference Between #include <...> and #include "..." in C and C++
Learn the difference between #include with angle brackets and quotes in C and C++, including search paths, examples, and common mistakes.