Open-Source Internship opportunity by OpenGenus for programmers. Apply now.
In this article, we have explained the use of calloc() function in C / C++ which is used for Dynamic Memory Allocation. We have explained it with code examples with different situations.
Table of contents:
- What is Calloc?
- What is Dynamic Memory Allocation?
- Examples of calloc()
- calloc() vs malloc()
- calloc(): pros & cons
Let us get started with calloc() in C/ C++.
What is Calloc?
The calloc() "contiguous allocation" function in C (and due to backwards compatibility: C++) allocates a block of memory for an array of objects and initializes all its bits to zero, it returns a pointer to the first byte of the allocated memory block if the allocation succeeds.
If the size is zero, the value returned depends on the implementation of the library. It may or may not be a null pointer.
But before we discuss the calloc() function, we need to know about the Dynamic Memory Allocation concepts:
*Above: calloc() allocating memory and initializing
What is Dynamic Memory Allocation?
Ever came across a problem where you are not aware about how much memory you need beforehand?
Dynamic Memory is a structure programming procedure that allows users to allocate the memory at the run time of a program.
With Dynamic Memory Allocation, we can allocate or deallocate the memory during the execution of a program. By doing so, it avoids the wastage of computer memory.
There are 3 library functions provided by C defined under <stdlib.h> header file to implement dynamic memory allocation in C programming:
- malloc()
- calloc()
- realloc()
We will be focusing on calloc() in this article
Examples of calloc()
Let us see some examples of use cases of calloc() with syntax
Using calloc()
ptr = (cast-type*)calloc(n, element-size);
- cast_type: Cast type is the data type you want to allocate memory to
- n: n is the number of elements
- element-size: size of each element
Return value:
This function returns a pointer to the allocated memory, or NULL if the request fails.
Example: Program to demostrate the use of calloc() with free()
The program below allocates memory using calloc() to store the numbers, then takes input of the numbers from the user and then prints out the numbers and their sum.
After doing that it frees the allocated memory using free()
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main() {
int n, *ptr, *p, i, sum = 0;
printf (" Enter the number of elements: ");
scanf (" %d", &n);
ptr = (int *) calloc (n, sizeof(int));
p = ptr;
if (ptr == NULL) {
printf (" Memory is not allocated. ");
exit(0);
}
printf (" Enter %d numbers \n", n);
for ( i = 1; i <= n; i++){
scanf ( "%d", ptr);
sum = sum + *ptr;
ptr++;
}
printf (" Elements are: ");
for (i = 1; i <= n; i++){
printf (" %d", *p);
p++;
}
printf (" \n The addition of the elements is: %d ", sum);
free(ptr);
getch();
}
Output:
Enter the number of elements: 5
Enter 5 numbers
1
2
3
4
5
Elements are: 1 2 3 4 5
The addition of the elements is: 15
Here is a step-by-step explanation of the above program:
- Declaring our variables and pointers,
int n, *ptr, *p, i, sum = 0;
- n: number of elements
- *ptr: store base address of the dynamic memory
- *p: store temporary address of the *ptr
- i: to iterate loops
- sum: to store the sum
- Taking the number of elements from the user,
printf (" Enter the number of elements: ");
scanf (" %d", &n);
- Using calloc to create a memory block of integer data type
ptr = (int *) calloc (n, sizeof(int));
- Assigning the address of pointer
p = ptr;
- Checking whether memory is allocated
If the ptr points to NULL, it means it hasn't been allocated
if (ptr == NULL) {
printf (" Memory is not allocated. ");
exit(0);
}
- Inputting the numbers and calculating it's sum
printf (" Enter %d numbers \n", n);
for ( i = 1; i <= n; i++){
scanf ( "%d", ptr);
sum = sum + *ptr;
ptr++;
}
- Displaying the numbers and it's sum
printf (" Elements are: ");
for (i = 1; i <= n; i++){
printf (" %d", *p);
p++;
}
printf (" \n The addition of the elements is: %d ", sum);
- Freeing the allocated space using free()
free(ptr);
getch();
free() is a method in C used to dynamically de-allocate memory.
More use cases of calloc()
Using calloc() for struct in C
#include <stdio.h>
struct employee {
char *name;
int salary;
};
typedef struct employee emp;
int main() {
emp *e1;
e1 = (emp*)calloc(30,sizeof(emp));
return 0;
}
Using calloc() for class in C++
#include <stdio.h>
class MyClass {
public:
int myNum;
string myString;
};
int main(){
MyClass *MyObj;
MyObj = (MyClass*)calloc(10,sizeof(MyClass));
return 0;
}
Now let's see calloc()'s comparison with malloc(), another C library function used for memory allocation
calloc() vs malloc()
To compare calloc() with malloc(), we need to first have a basic idea about the features of malloc()
malloc():
Key points:
- malloc() stands for "memory allocation"
- This method is used to dynamically allocate a single large block of memory with the required size.
- It returns a pointer of type void which can be casted into a pointer of any form.
Syntax:
mp = (cast_type*) malloc(byte_size);
- mp: pointer mp holds the address of the first byte in the allocated memory.
- cast_type: It determines data type of memory allocated.
- byte_size: It help us to determine byte of memory allocated
Return Value:
This function returns a pointer to the allocated memory, or NULL if the request fails.
We can achieve the same functionality as calloc() by using malloc() + memset(0)
ptr = malloc(size);
memset(ptr, 0, size);
The difference between malloc() and calloc()
- calloc() can assign multiple blocks of memory for a variable while malloc() creates a single block of memory of size specified by the user.
- The memory blocks allocated by calloc() are always initialized as 0, while malloc() doesn't initialize while allocating and hence returns a garbage value
- calloc() takes two arguments but malloc() takes just one
- calloc() is slower than malloc() but it's time efficiency is higher
calloc(): pros & cons
Pros:
- If you want to initialize your memory as 0 then you can use calloc(), using malloc() and then initializing it using memset(0) is more expensiver.
- calloc() can help you protect against integer overflow vulnerabilities:
Comparing,
size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);
vs
size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);
The former could result in a tiny allocation and subsequent buffer overflows, if count is greater than SIZE_MAX/sizeof *bar
. The latter will automatically fail in this case since an object that large cannot be created.
Cons:
- calloc() initializes your block of memory with 0 when you declare it, so initializing your block takes a some time. Use malloc() over calloc() for performance reasons.
When to use calloc()
- Allocating memory to contain a structure, where you want all the members initialised to zero.
- Allocating memory for an array of chars which you are later going to write some number of chars into, and then treat as a NULL terminated string.
- Allocating memory for an array of pointers which you want initialised to NULL.
When to not use calloc()
- If you don't need the dynamically allocated memory to be zero-initialized, then use malloc.
Now let's test your understanding:
Question:
Which of the following is/are true?
With this article at OpenGenus, you must have a strong idea of calloc() in C / C++ Programming.