Users Online

· Guests Online: 3

· Members Online: 0

· Total Members: 185
· Newest Member: meenachowdary055

Forum Threads

Newest Threads
No Threads created
Hottest Threads
No Threads created

Latest Articles

FAQ: C Dynamic Memory Allocation

FAQ (Frequently Asked Questions) >C Dynamic Memory Allocation
01 What is Difference Between Compile-Time and Run-Time Memory Allocation in C Programming02 What is a Pool of Free Memory and How is this Used in C?03 Explain Dynamic Memory Allocation in C with Examples04 Explain malloc(), calloc(), realloc() and free() in C Language with Examples
05 Common Errors During Dynamic Memory Allocation in C06 What is a Memory Leak in C08 Where is Memory Allocated During Dynamic Memory Allocation in C Programming
01 What is Difference Between Compile-Time and Run-Time Memory Allocation in C Programming
Question: What is Difference Between Compile-Time and Run-Time Memory Allocation in C Programming?
Answer: Let’s try out following programs, first,

/* compiletime_vs_runtime1.c -- program differentiates between two */
#include <stdio.h>

int main()
{
float marks[10];
int i;

puts("user, enter marks of 10 students...");
for (i = 0; i < 10; i++)
scanf("%f", &marks[i]);

puts("Marks of 10 students are:");
for (i = 0; i < 10; i++)
printf("%.2f ", marks[i]);

puts("");
return 0;
}
Output of the above program as,

user, enter marks of 10 students...
54
2
1
34
67
86
78
34
98
78
Marks of 10 students are:
54.00 2.00 1.00 34.00 67.00 86.00 78.00 34.00 98.00 78.00

What do you observe here as a limiting factor? You can process marks of up to max of 10 students. What about if you wished to process less than 10 or in a case more than 10 marks, say, marks of 100 students or 5 marks or even there’s a situation where you are not knowing in advance, how many?

O key, for sure, you declare an array with largest possible size, say 10000 elements size or larger than this, thinking program can now process any number of marks. But, still, there’s always a possibility of overflowing of array. And further worse to it, if just few marks to process, there’s a huge memory wastage. Actually, array size is a constant literal and compiler allocates, while compiling the program, enough memory to hold as much as elements defined by that constant.

Let’s take up with the case where we are not known in advance how many elements to process, till run time, say, 40 or 400 or just 5 or some other value. This could be solved if we would be able to write a program that asks user, at run time, how many elements to process, then allocates memory for specified no. of elements. No wastage of memory and program processes the desired no. of elements. Let’s try out such a case,

/* compiletime_vs_runtime2.c -- program differentiates between two */

#include <stdio.h>

int main()
{ int n, i;
float marks[n];

printf("How many marks to process? Enter a positive integer...\n");
scanf("%d", &n);

printf("now enter marks of students...\n");
for (i = 0; i < n; i++)
scanf("%f", &marks[i]);

printf("Processing %d Marks.\n", n);
return 0;
}
Let’s consider the output, for some arbitrary no.,

How many marks to process? Enter a positive integer...
5
now enter marks of students...
32
5.4
67.78
23.56
89
Processing 5 Marks.
So, what you observed here? Compiler didn’t allocate memory at compile time. Instead, program asked user, at runtime, no. of marks to process and allocated them memory and processed them. This technique is run time allocation. Though, run time allocation is efficient but program retained memory until it exited.
Top
02 What is a Pool of Free Memory and How is this Used in C?
Question: What is a Pool of Free Memory and How is this Used in C?
Answer: Two processes malloc() and free() maintain available memory in the System as pool of free memory for use by processes requiring dynamic allocation. When a program requests for dynamic allocation, malloc() attempts to allocate requested block of memory from this pool. If memory allocation is successful, program uses this chunk and after it’s done frees this up back to the pool by calling free() function.

If for reasons, say pool doesn’t have enough memory, malloc() may request the O.S. to arrange the requested chunk, O.S. tries to free up memory to this pool. But if O.S., too, failed, memory allocation to program gets failed. In this case, malloc() returns NULL pointer. Therefore, it’s mandatory to verify whether pointer returned by malloc() isn’t NULL before using it. Be careful not to dereference the NULL pointer!

You can write a subroutine to verify pointer returned by malloc(). Let’s consider a simple program,

/*
* malloc_free.c -- Let's allocate memory dynamically and free that
* up for reuse
*/

#include <stdio.h>
#include <stdlib.h> /* declarations for malloc(), free() etc. */

int main(void)
{
int *pi, i, nbytes = 0; /* by default nbytes value 0 */
void *p2v;

puts("\nLet's try to get memory chunk, specify number of bytes"
" u want...\n");
scanf("%d", &nbytes);
pi = malloc(nbytes);

printf("Now, we verify if required %d bytes allocated"
" successfully.\n", nbytes);
if (pi == NULL) {
puts("Error: Pool short of memory!");
exit(1);
}
else {
puts("Yes Succeeded!\n");
}

puts("Good! Now, let's use dynamic memory...\n");
printf("User type in %d integers one by one...\n",
nbytes / sizeof(int));
for (i = 0; i < nbytes / sizeof(int); i++)
scanf("%d", (pi + i));

puts("");

printf("User, let's see what had u typed...\n");
for (i = 0; i < nbytes / sizeof(int); i++)
printf("%d ", *(pi + i));

puts("");

puts("Let's return allocated memory to system for reuse.");
free(pi); /* free up memory */
puts("Thank you!\n");
return 0;
}
Let’s observe the output,

Let's try to get memory chunk, specify number of bytes u want...

20
Now, we verify if required 20 bytes allocated successfully.
Yes Succeeded!

Good! Now, let's use dynamic memory...

User type in 5 integers one by one...
23
12
432
34
22

User, let's see what had u typed...
23 12 432 34 22
Let's return allocated memory to system for reuse.
Thank you!
The syntax of malloc() and free() functions,

void *malloc(size_t num_of_bytes);
void free(void *);
When memory allocation is requested using malloc(), it tries to allocate the requested chunk and returns pointer of type void to the beginning of that chunk. We know that pointer to void can be converted to any other type. And memory allocated then be used by the program. One more thing is that memory allocated by malloc() is in no way initialized.

Further, malloc() allocates specified amount of memory as no. of bytes. So, in order to obtain memory for 10 integers, we better write as

int n = 10;
int *pi;

pi = (int *)malloc(n * sizeof(int));

Notice that malloc() returned type void * which converted to type int *. sizeof operator used to evaluate size of type int on a Linux machine which we multiplied by n to evaluate memory for 10 integers. The benefit obtained here is program is more portable as size of type int varies on different implementations.

After you are done with the allocation and no longer want to use it, return the block back to pool of free memory, by calling free(), for re-allocation to other part of your program or use by other process.

void free(pi);
If you didn’t return memory back to the pool immediately after you were no longer needed it, it would return to the pool when program exits. But till then program retained the block and so why it’s of no use to other processes.
Top
03 Explain Dynamic Memory Allocation in C with Examples
This C Tutorial explains Dynamic Memory Allocation in C with examples.
In simple means, when you required desired amount of memory, you are allocated, you worked up with and when you no longer needed that chunk you freed that back to the system. This way, you worked efficiently with memory usage i.e. program didn’t retain memory until it exited.

Consider an instance, suppose we need to maintain record of each employee in some organisation with new employees to join, older employees might leave, how about performing this efficiently using dynamic allocation. When new employee joins, we allocate memory and we free up when some one leaves. The memory returned to the system might be used by other parts of the same program or by other processes when they would require.

Let’s consider another example of dynamic allocation. Suppose, we read a line of input from a file, we required dynamic allocation and this grows when we read more of it from the file.

Dynamic allocation, actually, is of interest where we are not sure, in advance, until run time, how much memory would we require and this could grow if needed more of it and for how long. Further, we free up block when we are no longer required it. Remember that freeing up block at the end of program has no significant importance of dynamic allocation since all memory allocated to program returns when program exits.

Memory allocated to a program during compile time can’t be freed until program exits.
Two functions viz. malloc() and free() maintain free pool of available memory for dynamic allocation to programs.
Top
04 Explain malloc(), calloc(), realloc() and free() in C Language with Examples
This C Tutorial explains various Dynamic memory Allocation Functions viz. – malloc(), calloc(), realloc() and free() in C Language, with examples.
Functions malloc(), calloc(), realloc() are used for dynamic allocation while free() used for deallocation of block allocated to by malloc(), calloc() or realloc(). Let us differentiate among them by experimenting, first we consider malloc(),

/*
* malloc_not_ini.c -- program displays memory allocated by malloc is not
* initialized
*/
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *pc, chars, i;

puts("**Program displays malloc() returns uninitialized block**");
printf("Specify no. of characters to which memory to allocate,\n");
scanf("%d", &chars);

/* now allocate memory */
pc = (char *)malloc(chars * sizeof(char));

/* verify if allocation successful */
if (pc == NULL) {
puts("Error: Allocation Failed!");
exit(EXIT_FAILURE);
}

/* let us see the contents of allocated block */
i = 0;
printf("Allocated block, an array of %d chars, contains values:",
chars);
while (i < chars) {
printf("%2c", *(pc + i));
i++;
}

/* Now we free allocated block back to pool of available memory */
free(pc);

puts("");
return 0;
}
Output of the above program, for some arbitrary character’s value, as follows,

**Program displays malloc() returns uninitialized block**
Specify no. of characters to which memory to allocate,
25
Allocated block, an array of 25 chars, contains values:
Notice here that malloc() takes one argument, size in bytes, and allocates requested block of memory and returns pointer of type void * to the start of that block. If function fails, it returns NULL. Therefore, it’s mandatory to verify if pointer returned is NOT NULL. Further, block allocated isn’t initialized.

Let us consider calloc() now,

/*
* calloc_ini.c -- program displays memory allocated by calloc is
* initialized to 0
*/
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int *pi, ints, i;

puts("**Program displays calloc() initializes memory"
" It allocates**");
printf("Specify no. of integers to which memory to allocate,\n");
scanf("%d", &ints);

/* now allocate memory */
pi = (int *)calloc(ints, sizeof(int));

/* verify if allocation successful */
if (pi == NULL) {
puts("Error: Allocation Failed!");
exit(EXIT_FAILURE);
}

/* let us see if allocated block is initialized with zeroes */
i = 0;
printf("Allocated block, an array of %d ints, is initialized with:",
ints);
while (i < ints) {
printf("%2d", *(pi + i));
i++;
}

/* free block up back to pool of available memory */
free(pi);

puts("");
return 0;
}

Output as follows,

**Program displays calloc() initializes memory It allocates**
Specify no. of integers to which memory to allocate,
6
Allocated block, an array of 6 ints, is initialized with: 0 0 0 0 0 0
What we noticed here is that calloc() takes two arguments, first is number of elements and second is type of element and computes number of bytes to allocate. It allocates requested block and returns pointer to void pointing to beginning of block. If fails, returns NULL. Unlike malloc(), calloc() initializes the block with zeroes.

Next, we turn to consider is realloc(),

/*
* realloc.c -- Let's get resize previously allocated block and
* free that up for reuse
*/
/* void *realloc(void *, size_t num_bytes) */ /* realloc resizes */
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int *pi, i, num = 0;
int *pi1 = 0; /* pointer set to NULL */

puts("\nLet's try to get block of memory for integers u want...\n");
scanf("%d", &num);

/* assigned to int * type */
pi = malloc(num * sizeof(int));

/* confirm if allocation is done */
if (pi == NULL) {
puts("Error: System short of memory!");
exit(1);
}

puts("Good! Now, let's use dynamic memory...\n");
printf("User type in %d integers one by one...\n", num);
for (i = 0; i < num; i++)
scanf("%d", (pi + i));

puts("");

printf("User, let's see what had u typed...\n");
for (i = 0; i < num; i++)
printf("%3d", *(pi + i));

puts("");

puts("Yeah, I want to resize the previously allocated chunk,\n"
"specify another value for integers you want now...");
scanf("%d", &num);
/* reallocate block using realloc() function */
pi1 = realloc(pi, num * sizeof(int));

/* confirm if allocation is done */
if (pi1 == NULL) {
puts("Error: System short of memory!");
exit(1);
}

printf("Let's see the contents of resized block of %d integers.\n",
num);
for (i = 0; i < num; i++)
printf("%3d", *(pi1 + i));

puts("");

puts("Good! Now, let's use new chunk...\n");
printf("User type in %d integers one by one...\n", num);
for (i = 0; i < num; i++)
scanf("%d", (pi1 + i));

puts("");

printf("User, let's see what had u typed...\n");
for (i = 0; i < num; i++)
printf("%3d", *(pi1 + i));

puts("");
puts("Let's return allocated memory to system for reuse.");
free(pi1); /* remember don't double free up memory */

puts("Thank you!\n");
return 0;
}
Output of the above program,

Let us try to get block of memory for integers u want...

6
Good! Now, let's use dynamic memory...

User type in 6 integers one by one...
1
2
3
4
5
6

User, let us see what had u typed...
1 2 3 4 5 6
Yeah, I want to resize the previously allocated chunk,
specify another value for integers you want now...
5
Let us see the contents of resized block of 5 integers.
1 2 3 4 5
Good! Now, let's use new chunk...

User type in 5 integers one by one...
5
6
7
8
9

User, let us see what had u typed...
5 6 7 8 9
Let's return allocated memory to system for reuse.
Thank you!


Well! realloc() takes two arguments, first pointer to void and second is size in bytes. Since, realloc() can be used to resize the previously allocated block to by malloc() or calloc(). Therefore, first argument to realloc is pointer to the previously allocated block. realloc() allocates requested chunk to some other location, makes it larger or smaller as specified by the size and copies here contents of previously allocated block. Since, new block allocated is different from previously allocated one, make sure to use pointer returned by realloc()! After you are done, call free() to return the chunk back to pool of available memory.

Let’s consider free() function,

void free(void *);
free() function frees up chunk and returns it to the pool of available memory.
Top
05 Common Errors During Dynamic Memory Allocation in C
Question5: What are Common Errors Which Might Occur While Memory Being Allocated Dynamically in C?
Answer: Each dynamic allocation function allocates requested chunk from the pool of available memory and returns a pointer pointing to the beginning of the block. The most common error is dereferencing the pointer without verifying whether allocation is successful or not. Dynamic allocation function returns NULL in the event of insufficient memory in the pool of available memory.

Because NULL pointer points to nowhere. Dereferencing it causes abnormal program termination. So, before performing indirection on pointer returned to by dynamic allocation function, make sure it’s not NULL.


In case of resizing the previously allocated block using realloc(), use the pointer returned by realloc() and not the previous pointer. For example,

int main(void)
{
int *pi, num;

pi = (int *)malloc(num * sizeof(int));

/* make sure if chunk is allocated or not */
if (pi == NULL) {
/* allocation failed, exit program */
}

/* else use the chunk */

/* after your're done, free up memory */
return 0;
}
The other very common error occurs when we mistakenly free up allocated chunk more than once or we try to free up a part of it. For example,

int *pi;
int n = 10;

pi = malloc(n * sizeof(int));

/* all are invalid */
free(pi + 5 ); /* freeing a part of it */

/* free up more than once */
free(pi);
free(pi);
Top
06 What is a Memory Leak in C
Question: What is a Memory Leak in C
Answer: In systems, functions ‘malloc()’ and ‘free()’ maintain pool of available memory for use by processes under dynamic requirements. This pool of memory is a limited resource. If a program is allocated memory from this pool and it didn’t free up the chunk after it’s no longer required, then this leads to memory leak. This chunk of memory is freed only when program exits.

In situations, where dynamic allocation is no longer required to maintain, free up the chunk before program terminates. There’s no significance of freeing up allocation in the end of program; because, it’d be similar to retain memory till program exits. This is also memory leak!


Memory leak is a severe problem when a program is repeatedly requesting more memory indefinitely and not freeing up any. This will exhaust pool of available memory.

/* mem_leak.c -- program displays the concept of memory leak */
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *pi;
int num;

puts("**Let's unravel memory leak!**");
printf("User, read in size of block, an integer value, u want to allocate"
" memory: ");
scanf("%d", &num);

/* Let's try to allocate block */
pi = (int *)malloc(num * sizeof(int));

/* confirm if allocation successful */
if (pi == NULL) {
puts("System sort of memory!");
exit(1);
}

/* we are done with the allocation */
/* free up memory here */

/* other statements */

/* if u again required a dynamic block */
/* get that here again */

pi = (int *)malloc(num * sizeof(int));

/* free up when you are done */
return 0;
}
Top
08 Where is Memory Allocated During Dynamic Memory Allocation in C Programming
Question: Where is Memory Allocated During Dynamic Memory Allocation in C Programming
Answer: Dynamic memory allocation in which memory is more explicitly (but more flexibly) managed, typically, by allocating it from the free store (informally called the “heap”), an area of memory structured for this purpose. In C, the library function malloc() is used to allocate a block of memory on the heap.

The program accesses this block of memory via a pointer that malloc() returns. When the memory is no longer needed, the pointer is passed to free which deallocates the memory so that it can be used for other purposes. Dynamic memory allocation is a manual memory management technique.

Top
Render time: 0.30 seconds
7,458,472 unique visits