Additions:
Unlike malloc, calloc zeroes out the memory that it allocates. That is every bit of data that calloc allocates is zeroed out. This has its own usage which is beyond the scope of this discussion. There are however some problems associated with calloc. For more information check out the Advanced Section at the end of this article.
If you are reading this, then you can be sure that a situation wont arise in the near future where it is essential that you use calloc instead of malloc. For most of our day to day programming activities malloc would suffice. The memory that malloc allocates is not initialized to any particular value but it doesn't matter because we are going to allocate our own values to it. An attempt to use memory allocated by malloc without initializing it would lead to undefined behavior.
There is one reason why people might prefer using calloc over malloc. Normally when people want to allocate memory large enough to hold num elements where each element is size bytes large, they would call malloc like this:
But there is a problem here. What if num were very large so that the multiplication num*size causes an overflow on a size_t variable? On some systems when such an overflow occurs, the value is rounded down and the resulting value would be very different and much smaller when compared to the original result. And so malloc would attempt to allocate memory of that size and if successful it would return a pointer to this block of memory whose size would be very different from what we requested in the first place. This is bound to cause problems at a later point of time. A call to calloc like this <type of the element>* ptr=calloc(num,size); seems like a much better option. But you can rest assured that if the memory requested is so large so as to cause an overflow on a size_t value then the requested block of memory would be too big to fit into the memory available on most computers. So the usage of calloc doesn't improve the situation much and such a call is bound to fail anyway.
Deletions:
Unlike malloc, calloc zeroes out the memory that it allocates. That is every bit of data that calloc allocates is zeroed out. This has its own usage which is beyond the scope of this discussion. There are however some problems associated with calloc. For mode information check out the Advanced Section at the end of this article. If you are reading this, then you can be sure that a situation wont arise in the near future where it is essential that you use calloc instead of malloc. For most of our day to day programming activities malloc would suffice. The memory that malloc allocates is not initialized to any particular value but it doesnt matter because we are going to allocate our own values to it. An attempt to use memory allocated by malloc without initializing it would lead to incorrect results.
There is one reason why people might prefer using calloc over malloc. Normally when people want to allocate memory large enough to hold num elements where each element is size bytes large, they would call malloc like this
But there is a problem here. What if num were very large so that the multiplication num*size causes an overflow on a size_t variable? On some systems when such an overflow occurs the value is rounded down and the resulting value would be very different and much smaller when compared to the original result. And so malloc would attempt to allocate memory of that size and if successful it would return a pointer to this block of memory whose size would be very different from what we requested in the first place. This is bound to cause problems at a later point of time. A call to calloc like this <type of the element>* ptr=calloc(num,size); seems like a much better option. But you can rest assured that if the memory requested is so large so as to cause an overflow on a size_t value then the requested block of memory would be too big to fit into the memory available on most computers. So the usage of calloc doesnt improve the situation much and such a call is bound to fail anyway.
Edited on
2008-07-16 04:34:56 by SharathAV
[Seperation of Dynamic Alocation of Memory explanation from difference between malloc and calloc.]
Additions:
What are the differences between allocation of memory using malloc() and calloc() ?
Deletions:
What is dynamic memory allocation?
Memory can be managed either
statically or
automatically. Variables that are static are allocated in a fixed memory (this part needs a bit more explanation. Will come to that later) and persist for the program's lifetime. They retain values between function calls but are visible only in the scope in which they were declared. Automatic variables however are allocated on the stack on most implementations. They are destroyed once the function in which they were declared returns and so they go out of scope. The memory that they occupied is often freed for occupation by some other variable.
//example.c
#include <stdio.h>
int func(void){
int temp=0; //local variable. Is destroyed after this function exits. Is typically allocated on the stack
static int ret=0; //static value. Persists for the program's lifetime. Is typically allocated in a fixed memory.
temp++;
ret++;
printf("temp:%d ret:%d\n",temp,ret);
}
int main(){
for(int i=0;i<5;i++)
func();
}
//The output would be
//temp:1 ret:1
//temp:1 ret:2
//temp:1 ret:3
//temp:1 ret:4
//temp:1 ret:5
You can see that the static variable
ret retains its value between function calls while
temp doesnt.
Static allocation and automatic allocation have their own disadvantages. Automatic duration memory cannot be persisted with between function calls and it is freed once the variable goes out of scope. Static allocation on the other hand persists for the program's lifetime and this can be a hassle too when we dont want it to persist through the program's lifetime.
Dynamic memory comes handy here and offers flexible memory management. It is often used when you cant determine how much memory would be required before your program runs. For example: The length of an array might not be known beforehand and hence such an array cannot be allocated statically during compile time. Dynamic memory allocation comes handy during such situations. An area of memory called the heap is available for the C runtime enviroment to handle dynamic memory allocation requests. Any request to allocate memory dynamically, allocates memory on the heap. Once we are done with this memory we can always release this memory which would make this memory avaiable for other parts of your program.
At this point of time I would also like to add that the standard doesnt specifically mention anything about where variables need to be stored. Various compiler vendors choose different memory map layouts and this doesnt violate the standard. For example: a particular vendor may choose to store globals and statics on the heap and someone else might choose not to do so. For our purposes we will just assume that static variables are allocated in fixed memory, automatic variables on the stack and dynamic variable on the heap. It wont affect our discussion much as what follows is an implementation independent perspective.
malloc and calloc:
malloc and calloc are functions used for performing dynamic memory allocations in C. malloc is an often used function in C programs and if you want to be considered a good programmer you must learn to use it.
The prototype for malloc and calloc is as follows:
void* malloc(size_t size);
void* calloc(size_t num, size_t size);
These functions are declared in the header file
stdlib.h. It would be better to include this file (not necessary) in programs using malloc or calloc for reasons I will mention later.
malloc is used to allocate size bytes of memory. If the call to malloc was successful i.e. if enough memory is avaiable for malloc to be able to process the call then malloc allocates size bytes of memory and returns a pointer to this block of memory. If it was unsuccessful then a null pointer is returned. It is very important to check the pointer returned by malloc and see if it is a null pointer. If we dont do this and attempt to use the null pointer then the program would crash during runtime.
calloc on the other takes two parameters instead of one like malloc. The first parameter
num tells calloc the number of elements for which memory needs to be allocated and the second parameter
size tells calloc the size of each element. Typically calloc allocates memory that would be num*size bytes large. Once the memory allocation is successful calloc returns a pointer to this block of memory like malloc does. If it insuccessful then a null pointer is returned.
Difference between malloc and calloc:
Releasing memory:
Now comes the most important section. Any memory that has been allocated by malloc or calloc remains allocated unless we specify that we have no use for this block of memory and request that the memory be released for other usage. This is done by a call to free.
The prototype for free is
void free(void*);
It is very important that the pointer returned from a call to malloc or calloc be eventually passed to free function. This releases the allocated memory and it becomes available for other parts of your program. If we forget to call free on a particular block of memory when we have no use for it, then that block remains allocated until the process itself exits and in programming parlance this is called a
memory leak.
It is usually considered to be a bad programming practice to not free memory explicitly when we have no use for it.
I will show you a very simple program that uses malloc.
#include <stdlib.h> //it is necessary to include this header file for reasons I will mention later
#include<stdio.h>
int main(void){
{
int *a=0; //a is visible only within this block
const int num=10;
a=malloc(sizeof(int)*num); //allocates memory large enough to hold 10 int values
//Initializing the allocated memory
for (int i=0;i<10;i++){
a[i]=i+1;
}
//Use the allocated memory here
//.............
//.............
//Memory is no longer needed. So free it
free(a); //if we forget this step and the pointer "a" goes out of scope then we have a memory leak
a=NULL;//to prevent accidental reuse
}
}
Don't cast the value returned by malloc or calloc:
If you check my program above you can see that I havent cast the void* pointer that malloc returned to an int*. This is because the C Standard guarantees safe implicit conversion from a void* pointer to any other pointer type except the function pointer. Such a cast therefore becomes unnecessary and an
attempt to cast the pointer returned by malloc or calloc is considered to be a bad programming practice.
This is because most of the programmers normally forget to include the necessary header files when they use certain functions. For library functions this is
usually not a problem because the linker can always link the necessary object files during link time. This can however be a problem when a newbie attempts to use malloc without including stdlib.h in their programs. When we dont include stdlib.h in our programs then the compiler would most likely assume that malloc is a function which returns int (the default value).
So a statement like
int* a=malloc(sizeof(int)*num) would fortunately cause most compilers to emit a warning because we are trying to convert an int to int*. This alerts the programmer. The problem is because you forgot to include stdlib.h and not because you dont have an explicit cast from int to int*.
If the programmer attempts to correct the above problem with a cast like this: "int* a=(int*)malloc(sizeof(int)*num)" then the compiler wouldnt warn you. It would just shut up assuming that you know what you are doing. Ofcourse this is wrong because you are trying to convert the int that malloc doesnt return to an int*assuming that malloc returns an int. This can lead to serious bugs. So a cast is best avoided.
Using freed memory:
Once a pointer has been passed to free it points to a region of memory which may or may not be available for use. An attempt to use this pointer would lead to undefined results. Always remember to assign NULL to pointers on which free has been called. An attempt to use this pointer would crash the program during runtime but that is certainly better than using a freed pointer directly which leads to undefined results thus making bug tracking very difficult.
Freeing an already freed pointer:
An attempt to free a pointer that has already been freed leads to undefined behavior. So it is essential that you assign NULL to pointers that are freed because an attempt to free a NULL pointer is well defined and it doesnt do anything.
Deletions:
licotr
pasc4t
Additions:
licotr
Additions:
pasc4t
Additions:
If you check my program above you can see that I havent cast the void* pointer that malloc returned to an int*. This is because the C Standard guarantees safe implicit conversion from a void* pointer to any other pointer type except the function pointer. Such a cast therefore becomes unnecessary and an attempt to cast the pointer returned by malloc or calloc is considered to be a bad programming practice.
Deletions:
If you check my program above you can see that I havent cast the void* pointer that malloc returned to an int*. This is because the C Standard guarantees an implicit conversion from a void* pointer to any other pointer type except the function pointer. Such a cast therefore becomes unnecessary and an attempt to cast the pointer returned by malloc or calloc is considered to be a bad programming practice.
Additions:
If you check my program above you can see that I havent cast the void* pointer that malloc returned to an int*. This is because the C Standard guarantees an implicit conversion from a void* pointer to any other pointer type except the function pointer. Such a cast therefore becomes unnecessary and an attempt to cast the pointer returned by malloc or calloc is considered to be a bad programming practice.
Deletions:
If you check my program above you can see that I havent cast the void* pointer that malloc returned to an int*. This is because the C Standard guarantees an implicit conversion from a void* pointer to any other pointer type. Such a cast therefore becomes unnecessary and an attempt to cast the pointer returned by malloc or calloc is considered to be a bad programming practice.
Additions:
Additions:
Unlike malloc, calloc zeroes out the memory that it allocates. That is every bit of data that calloc allocates is zeroed out. This has its own usage which is beyond the scope of this discussion. There are however some problems associated with calloc. For mode information check out the Advanced Section at the end of this article. If you are reading this, then you can be sure that a situation wont arise in the near future where it is essential that you use calloc instead of malloc. For most of our day to day programming activities malloc would suffice. The memory that malloc allocates is not initialized to any particular value but it doesnt matter because we are going to allocate our own values to it. An attempt to use memory allocated by malloc without initializing it would lead to incorrect results.
Deletions:
Unlike malloc, calloc zeroes out the memory that it allocates. That is every bit of data that calloc allocates is zeroed out. This has its own usage which is beyond the scope of this discussion. If you are reading this, then you can be sure that a situation wont arise in the near future where it is essential that you use calloc instead of malloc. For most of our day to day programming activities malloc would suffice. The memory that malloc allocates is not initialized to any particular value but it doesnt matter because we are going to allocate our own values to it. An attempt to use memory allocated by malloc without initializing it would lead to incorrect results.
Additions:
At this point of time I would also like to add that the standard doesnt specifically mention anything about where variables need to be stored. Various compiler vendors choose different memory map layouts and this doesnt violate the standard. For example: a particular vendor may choose to store globals and statics on the heap and someone else might choose not to do so. For our purposes we will just assume that static variables are allocated in fixed memory, automatic variables on the stack and dynamic variable on the heap. It wont affect our discussion much as what follows is an implementation independent perspective.
But you are horribly wrong here. The 10 int* pointers that you have here may or may not be null pointers. The zero-fill is guaranteed to yield zero value for all int types (including char) but it does not guarantee null values for pointers and zero values for floating points.
Deletions:
At this point of time I would also like to add that the standard doesnt specifically mention anything about where variables need to be stored. Various compiler vendors choose different memory map layouts and this doesnt violate the standard. For example: a particular vendor may choose to store globals and statics on the heap and someone else might choose not to do so. For our purposes we will just assume that static variables are allocated in fixed memory, automatic variables on the stack and dynamic variable on the heap. It wont affect our discussion much as what follows is an implementation free perspective.
But you are horribly wrong here. The 10 int* pointers that you have here may or may not be equal to NULL. The zero-fill is guaranteed to yield zero value for all int types (including char) but it does not guarantee NULL values for pointers and zero value for floating points.
Additions:
Advanced section
It is often better to avoid the usage of calloc as far as possible. Use it only when you have to. For everything else there is malloc.
As has already been mentioned before, calloc zeroes out the memory that it allocates which means that every bit in the memory block allocated by calloc is zero. People might find this useful at times. For eg: if they wanted to allocate a block of memory large enough to hold 10 integer values an if they wanted to initialize all these values to zero then all that they have to do is to call calloc like this:
int* ptr=calloc(10,sizeof(int));
Here all the int values are zero to start out with. Hmmm that was very easy.
Now suppose someone else wanted to allocate memory for 10 int* variables and wanted to initialize all these values to NULL i.e he/she wanted all the int* pointers to be zero. Now you might think that we could use calloc again for this like this:
int** ptr=calloc(10,sizeof(int*));
But you are horribly wrong here. The 10
int* pointers that you have here may or may not be equal to NULL. The zero-fill is guaranteed to yield zero value for all int types (including char) but it does not guarantee NULL values for pointers and zero value for floating points.
A null pointer is something that is distinguishable from all other pointers and is guaranteed to compare unequal to any pointer that points to any object or function. And how can null pointers be generated? It is again guaranteed by the standard that assigning zero to a pointer makes that pointer a null pointer. Read it carefully again.
"Assigning zero to a pointer makes that pointer a null pointer".
This does not mean that the memory region in which the null pointer is stored is filled with zeroes. When you assign zero to a pointer, things happen under the hood which guarantees the return of a null pointer. What happens underneath is implementation defined and in particular architecture dependent. So different compilers might follow different methods.
So when you use calloc to allocate memory to store 10 int* null pointers, you would go horribly wrong. What you have here are not 10 null pointers. They could be anything (it is fairly obvious that they wont be pointing to a well defined region of memory). So it is better not to use calloc to allocate memory for pointers and if you do, you better not assume that these are null pointers.
For more info on NULL and null pointers please refer to
C-FAQ∞.
For those who are wondering if sane discussions ever take place in Orkut please check this
Orkut link∞ and in particular check the contributions of
Lenson Andrade, C and AV Sharath. They have discussed pretty much what I have written here.
Revision [81]
Edited on
2006-10-12 04:45:44 by 155.69.5.236 (unregistered user)
[Edited by Sacred Feminine aka Priya]
Additions:
Once a pointer has been passed to free it points to a region of memory which may or may not be available for use. An attempt to use this pointer would lead to undefined results. Always remember to assign NULL to pointers on which free has been called. An attempt to use this pointer would crash the program during runtime but that is certainly better than using a freed pointer directly which leads to undefined results thus making bug tracking very difficult.
Deletions:
Once a pointer has been passed to free it points to a region of memory which may or may not be available for use. An attempt to use this pointer would lead to undefined results. Always remember to assign NULL to pointers on which free has been called. An attempt to use this pointer would crash the program during runtime but that is certainly better than using this pointer which leads to undefined results which makes tracking bugs very difficult.
Additions:
But there is a problem here. What if num were very large so that the multiplication num*size causes an overflow on a size_t variable? On some systems when such an overflow occurs the value is rounded down and the resulting value would be very different and much smaller when compared to the original result. And so malloc would attempt to allocate memory of that size and if successful it would return a pointer to this block of memory whose size would be very different from what we requested in the first place. This is bound to cause problems at a later point of time. A call to calloc like this <type of the element>* ptr=calloc(num,size); seems like a much better option. But you can rest assured that if the memory requested is so large so as to cause an overflow on a size_t value then the requested block of memory would be too big to fit into the memory available on most computers. So the usage of calloc doesnt improve the situation much and such a call is bound to fail anyway.
Deletions:
But there is a problem here. What if num were very large so that the multiplication num*size causes an overflow on a size_t variable? On some systems when such an overflow occurs the value is rounded down and the resulting value would be very different and much smaller when compared to the original result. And so malloc would attempt to allocate memory of that size and if successful it would return a pointer to this block of memory whose size would be very different from what we requested in the first place. This is bound to cause problems at a later point of time. A call to calloc like this <type of the element>* ptr=calloc(num,size); seems like a much better option. But you can be assured that if an overflow occurs on a size_t value then the requested block of memory would be too big to fit into the memory avaiable on most computers. So the usage of calloc doesnt improve the situation much and such a call is bound to fail anyway.
Additions:
What is dynamic memory allocation?
Memory can be managed either statically or automatically. Variables that are static are allocated in a fixed memory (this part needs a bit more explanation. Will come to that later) and persist for the program's lifetime. They retain values between function calls but are visible only in the scope in which they were declared. Automatic variables however are allocated on the stack on most implementations. They are destroyed once the function in which they were declared returns and so they go out of scope. The memory that they occupied is often freed for occupation by some other variable.
malloc and calloc:
The prototype for malloc and calloc is as follows:
void* malloc(size_t size);
void* calloc(size_t num, size_t size);
These functions are declared in the header file stdlib.h. It would be better to include this file (not necessary) in programs using malloc or calloc for reasons I will mention later.
Difference between malloc and calloc:
Unlike malloc, calloc zeroes out the memory that it allocates. That is every bit of data that calloc allocates is zeroed out. This has its own usage which is beyond the scope of this discussion. If you are reading this, then you can be sure that a situation wont arise in the near future where it is essential that you use calloc instead of malloc. For most of our day to day programming activities malloc would suffice. The memory that malloc allocates is not initialized to any particular value but it doesnt matter because we are going to allocate our own values to it. An attempt to use memory allocated by malloc without initializing it would lead to incorrect results.
There is one reason why people might prefer using calloc over malloc. Normally when people want to allocate memory large enough to hold num elements where each element is size bytes large, they would call malloc like this
<type of the element>* ptr=malloc(num*size);
But there is a problem here. What if num were very large so that the multiplication num*size causes an overflow on a size_t variable? On some systems when such an overflow occurs the value is rounded down and the resulting value would be very different and much smaller when compared to the original result. And so malloc would attempt to allocate memory of that size and if successful it would return a pointer to this block of memory whose size would be very different from what we requested in the first place. This is bound to cause problems at a later point of time. A call to calloc like this <type of the element>* ptr=calloc(num,size); seems like a much better option. But you can be assured that if an overflow occurs on a size_t value then the requested block of memory would be too big to fit into the memory avaiable on most computers. So the usage of calloc doesnt improve the situation much and such a call is bound to fail anyway.
Releasing memory:
The prototype for free is void free(void*);
It is very important that the pointer returned from a call to malloc or calloc be eventually passed to free function. This releases the allocated memory and it becomes available for other parts of your program. If we forget to call free on a particular block of memory when we have no use for it, then that block remains allocated until the process itself exits and in programming parlance this is called a memory leak. It is usually considered to be a bad programming practice to not free memory explicitly when we have no use for it.
Don't cast the value returned by malloc or calloc:
If you check my program above you can see that I havent cast the void* pointer that malloc returned to an int*. This is because the C Standard guarantees an implicit conversion from a void* pointer to any other pointer type. Such a cast therefore becomes unnecessary and an attempt to cast the pointer returned by malloc or calloc is considered to be a bad programming practice.
So a statement like int* a=malloc(sizeof(int)*num) would fortunately cause most compilers to emit a warning because we are trying to convert an int to int*. This alerts the programmer. The problem is because you forgot to include stdlib.h and not because you dont have an explicit cast from int to int*.
Using freed memory:
Freeing an already freed pointer:
Deletions:
Memory can be managed either statically or dynamically. Variables that are static are allocated in a fixed memory (this part needs a bit more explanation. Will come to that later) and persist for the program's lifetime. They retain values between function calls but are visible only in the scope in which they were declared. Automatic variables however are allocated on the stack on most implementations. They are destroyed once the function in which they were declared returns and so they go out of scope. The memory that they occupied is often freed for occupation by some other variable.
The prototype for malloc and calloc is as follows:
"void* malloc(size_t size);"
"void* calloc(size_t num, size_t size);"
These functions are declared in the header file stdlib.h. It would be better to include this file (not necessary) in programs using malloc or calloc for reasons I will mention later.
Unlike malloc, calloc however zeroes out the memory that it allocates. That is every bit of data that calloc allocates is zeroed out. This has its own usage which is beyond the scope of this discussion. If you are reading this, then you can be sure that a situation wont arise in the near future where it is essential that you use calloc instead of malloc. For most of our day to day programming activities malloc would suffice. The memory that malloc allocates is not initialized to any particular value but it doesnt matter because we are going to allocate our own values to it. An attempt to use memory allocated by malloc without initializing it would lead to incorrect results.
The prototype for free is "void free(void * pointer);"
It is very important that the pointer returned from a call to malloc or calloc be eventually passed to free function. This releases the allocated memory and it becomes available for other parts of your program. If we forget to call free on a particular block of memory when we have no use for it, then that block remains allocated until the process itself exits and in programming parlance this is called a memory leak. It is usually considered to be a bad programming practice to not free memory explicitly when we have no use for it.
If you check my program again you can see that I havent cast the void* pointer that malloc returned to an int*. This is because the C Standard guarantees an implicit conversion from a void* pointer to any other pointer type. Such a cast therefore becomes unnecessary and an attempt to cast the pointer returned by malloc or calloc is considered to be a bad programming practice.
So a statement like "int* a=malloc(sizeof(int)*num)" would fortunately cause most compilers to emit a warning because we are trying to convert an int to int*. This alerts the programmer. The problem is because you forgot to include stdlib.h and not because you dont have an explicit cast from int to int*.
Additions:
a=NULL;to prevent accidental reuse
Once a pointer has been passed to free it points to a region of memory which may or may not be available for use. An attempt to use this pointer would lead to undefined results. Always remember to assign NULL to pointers on which free has been called. An attempt to use this pointer would crash the program during runtime but that is certainly better than using this pointer which leads to undefined results which makes tracking bugs very difficult.
An attempt to free a pointer that has already been freed leads to undefined behavior. So it is essential that you assign NULL to pointers that are freed because an attempt to free a NULL pointer is well defined and it doesnt do anything.
Deletions:
The inclusion of header files tells the compiler the prototype of the function that you are trying to call
Additions:
#include <stdlib.h> it is necessary to include this header file for reasons I will mention later
const int num=10;
a=malloc(sizeof(int)*num); allocates memory large enough to hold 10 int values
If you check my program again you can see that I havent cast the void* pointer that malloc returned to an int*. This is because the C Standard guarantees an implicit conversion from a void* pointer to any other pointer type. Such a cast therefore becomes unnecessary and an
attempt to cast the pointer returned by malloc or calloc is considered to be a bad programming practice.
This is because most of the programmers normally forget to include the necessary header files when they use certain functions. For library functions this is
usually not a problem because the linker can always link the necessary object files during link time. This can however be a problem when a newbie attempts to use malloc without including stdlib.h in their programs. When we dont include stdlib.h in our programs then the compiler would most likely assume that malloc is a function which returns int (the default value).
So a statement like "int* a=malloc(sizeof(int)*num)" would fortunately cause most compilers to emit a warning because we are trying to convert an int to int*. This alerts the programmer. The problem is because you forgot to include stdlib.h and not because you dont have an explicit cast from int to int*.
If the programmer attempts to correct the above problem with a cast like this: "int* a=(int*)malloc(sizeof(int)*num)" then the compiler wouldnt warn you. It would just shut up assuming that you know what you are doing. Ofcourse this is wrong because you are trying to convert the int that malloc doesnt return to an int*assuming that malloc returns an int. This can lead to serious bugs. So a cast is best avoided.
The inclusion of header files tells the compiler the prototype of the function that you are trying to call
Deletions:
#include <stdlib.h> it is not necessary to include this header file but it can be useful for reasons I will mention later
a=malloc(sizeof(int)*10); allocates memory large enough to hold 10 int values
Additions:
At this point of time I would also like to add that the standard doesnt specifically mention anything about where variables need to be stored. Various compiler vendors choose different memory map layouts and this doesnt violate the standard. For example: a particular vendor may choose to store globals and statics on the heap and someone else might choose not to do so. For our purposes we will just assume that static variables are allocated in fixed memory, automatic variables on the stack and dynamic variable on the heap. It wont affect our discussion much as what follows is an implementation free perspective.
"void* malloc(size_t size);"
"void* calloc(size_t num, size_t size);"
These functions are declared in the header file stdlib.h. It would be better to include this file (not necessary) in programs using malloc or calloc for reasons I will mention later.
malloc is used to allocate size bytes of memory. If the call to malloc was successful i.e. if enough memory is avaiable for malloc to be able to process the call then malloc allocates size bytes of memory and returns a pointer to this block of memory. If it was unsuccessful then a null pointer is returned. It is very important to check the pointer returned by malloc and see if it is a null pointer. If we dont do this and attempt to use the null pointer then the program would crash during runtime.
calloc on the other takes two parameters instead of one like malloc. The first parameter
num tells calloc the number of elements for which memory needs to be allocated and the second parameter
size tells calloc the size of each element. Typically calloc allocates memory that would be num*size bytes large. Once the memory allocation is successful calloc returns a pointer to this block of memory like malloc does. If it insuccessful then a null pointer is returned.
Unlike malloc, calloc however zeroes out the memory that it allocates. That is every bit of data that calloc allocates is zeroed out. This has its own usage which is beyond the scope of this discussion. If you are reading this, then you can be sure that a situation wont arise in the near future where it is essential that you use calloc instead of malloc. For most of our day to day programming activities malloc would suffice. The memory that malloc allocates is not initialized to any particular value but it doesnt matter because we are going to allocate our own values to it. An attempt to use memory allocated by malloc without initializing it would lead to incorrect results.
Now comes the most important section. Any memory that has been allocated by malloc or calloc remains allocated unless we specify that we have no use for this block of memory and request that the memory be released for other usage. This is done by a call to free.
The prototype for free is "void free(void * pointer);"
It is very important that the pointer returned from a call to malloc or calloc be eventually passed to free function. This releases the allocated memory and it becomes available for other parts of your program. If we forget to call free on a particular block of memory when we have no use for it, then that block remains allocated until the process itself exits and in programming parlance this is called a memory leak. It is usually considered to be a bad programming practice to not free memory explicitly when we have no use for it.
I will show you a very simple program that uses malloc.
#include <stdlib.h> it is not necessary to include this header file but it can be useful for reasons I will mention later
int main(void){
{
int *a=0; a is visible only within this block
a=malloc(sizeof(int)*10); allocates memory large enough to hold 10 int values
Initializing the allocated memory
for (int i=0;i<10;i++){
a[i]=i+1;
}
Use the allocated memory here
.............
.............
Memory is no longer needed. So free it
free(a); if we forget this step and the pointer "a" goes out of scope then we have a memory leak
}
}
Deletions:
At this point of time I would also like to add that the standard doesnt mention anything about where variables need to be stored. Various compiler vendors choose different memory map layout and this doesnt violate the standard. For example: a particular vendor may choose to store globals and statics on the heap and someone else might choose not to do so. For our purposes we will just assume that static variables are allocated in fixed memory, automatic variables on the stack and dynamic variable on the heap. It wont affect our discussion much as what follows is an implementation free perspective.
void* malloc(size_t size);
void* calloc(size_t num, size_t size);
malloc is used to allocate
Revision [69]
The oldest known version of this page was edited on
2006-10-12 01:38:14 by PriyaSridharan
[Edited by Sacred Feminine aka Priya]
malloc and calloc are functions used for performing dynamic memory allocations in C. malloc is an often used function in C programs and if you want to be considered a good programmer you must learn to use it.
Memory can be managed either statically or dynamically. Variables that are static are allocated in a fixed memory (this part needs a bit more explanation. Will come to that later) and persist for the program's lifetime. They retain values between function calls but are visible only in the scope in which they were declared. Automatic variables however are allocated on the stack on most implementations. They are destroyed once the function in which they were declared returns and so they go out of scope. The memory that they occupied is often freed for occupation by some other variable.
//example.c
#include <stdio.h>
int func(void){
int temp=0; //local variable. Is destroyed after this function exits. Is typically allocated on the stack
static int ret=0; //static value. Persists for the program's lifetime. Is typically allocated in a fixed memory.
temp++;
ret++;
printf("temp:%d ret:%d\n",temp,ret);
}
int main(){
for(int i=0;i<5;i++)
func();
}
//The output would be
//temp:1 ret:1
//temp:1 ret:2
//temp:1 ret:3
//temp:1 ret:4
//temp:1 ret:5
You can see that the static variable
ret retains its value between function calls while
temp doesnt.
Static allocation and automatic allocation have their own disadvantages. Automatic duration memory cannot be persisted with between function calls and it is freed once the variable goes out of scope. Static allocation on the other hand persists for the program's lifetime and this can be a hassle too when we dont want it to persist through the program's lifetime.
Dynamic memory comes handy here and offers flexible memory management. It is often used when you cant determine how much memory would be required before your program runs. For example: The length of an array might not be known beforehand and hence such an array cannot be allocated statically during compile time. Dynamic memory allocation comes handy during such situations. An area of memory called the heap is available for the C runtime enviroment to handle dynamic memory allocation requests. Any request to allocate memory dynamically, allocates memory on the heap. Once we are done with this memory we can always release this memory which would make this memory avaiable for other parts of your program.
At this point of time I would also like to add that the standard doesnt mention anything about where variables need to be stored. Various compiler vendors choose different memory map layout and this doesnt violate the standard. For example: a particular vendor may choose to store globals and statics on the heap and someone else might choose not to do so. For our purposes we will just assume that static variables are allocated in fixed memory, automatic variables on the stack and dynamic variable on the heap. It wont affect our discussion much as what follows is an implementation free perspective.
The prototype for malloc and calloc is as follows:
void* malloc(size_t size);
void* calloc(size_t num, size_t size);
malloc is used to allocate