Dynamic Memory Allocation
Dynamic memory allocation in C allows you to allocate memory at runtime, which can be very useful for
managing memory in situations where you do not know the exact amount of memory needed during
compile time. The standard library(stdlib.h) in C provides several functions for dynamic memory
allocation, including malloc(), calloc(), realloc(), and free(). Here's a brief overview of each:
malloc(): Allocates a specified number of bytes and returns a pointer to the allocated memory. The
memory is not initialized.
#include <stdlib.h>
int *arr = (int *)malloc(10 * sizeof(int));
if (arr == NULL) {
// handle memory allocation failure
}
calloc(): Allocates memory for an array of elements, initializes all bytes to zero, and returns a pointer to
the allocated memory.
#include <stdlib.h>
int *arr = (int *)calloc(10, sizeof(int));
if (arr == NULL) {
// handle memory allocation failure
}
realloc(): Resizes the memory block pointed to by a pointer to a new size. If the new size is larger, the
additional memory is uninitialized.
#include <stdlib.h>
int *arr = (int *)malloc(10 * sizeof(int));
if (arr == NULL) {
// handle memory allocation failure
}
arr = (int *)realloc(arr, 20 * sizeof(int));
if (arr == NULL) {
// handle memory allocation failure
}
free(): Deallocates the memory previously allocated by malloc(), calloc(), or realloc().
#include <stdlib.h>
free(arr);
arr = NULL; // It's a good practice to set the pointer to NULL after freeing
Example:
malloc()
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
int *arr;
printf("Enter the number of elements: ");
scanf("%d", &n);
// Allocate memory for n integers
arr = (int *)malloc(n * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Initialize array elements
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
// Print array elements
printf("Array elements: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Free allocated memory
free(arr);
return 0;
}
calloc()
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i;
int *arr;
printf("Enter the number of elements: ");
scanf("%d", &n);
arr = (int *)calloc(n, sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Initialize array elements
for (i = 0; i < n; i++) {
arr[i] = i + 1;
}
// Print array elements
printf("Array elements: ");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Free allocated memory
free(arr);
return 0;
}
realloc()
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5; // initial number of elements
int new_n = 10; // new number of elements
int i;
int *arr;
arr = (int *)malloc(n * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Initialize array elements
for (i = 0; i < n; i++) {
arr[i] = i + 1;
}
// Print original array elements
printf("Original array elements: ");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Resize the array using realloc
arr = (int *)realloc(arr, new_n * sizeof(int));
if (arr == NULL) {
printf("Memory reallocation failed!\n");
return 1;
}
// Initialize new elements if the array is expanded
for (i = n; i < new_n; i++) {
arr[i] = i + 1;
}
// Print resized array elements
printf("Resized array elements: ");
for (i = 0; i < new_n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Free allocated memory
free(arr);
return 0;
}
File handling in C
File handling in C allows you to create, open, read, write, and close files. The standard library provides
several functions for file operations, which are declared in the <stdio.h> header file.
Opening a File:
• FILE *fopen(const char *filename, const char *mode);
• Modes: "r" (read), "w" (write), "a" (append), "r+" (read/update), "w+" (write/update), "a+"
(append/update).
Closing a File:
• int fclose(FILE *stream);
Writing to a File:
• int fprintf(FILE *stream, const char *format, ...);
• int fputs(const char *str, FILE *stream);
• int fputc(int char, FILE *stream);
Reading from a File:
• int fscanf(FILE *stream, const char *format, ...);
• char *fgets(char *str, int n, FILE *stream);
• int fgetc(FILE *stream);
Ex:
#include <stdio.h>
int main() {
FILE *sourceFile, *destFile;
char ch;
// Open source file for reading
sourceFile = fopen("source.txt", "r");
if (sourceFile == NULL) {
printf("Error opening source file!\n");
return 1;
}
// Open destination file for writing
destFile = fopen("destination.txt", "w");
if (destFile == NULL) {
printf("Error opening destination file!\n");
fclose(sourceFile);
return 1;
}
// Copy contents from source file to destination file
while ((ch = fgetc(sourceFile)) != EOF) {
fputc(ch, destFile);
}
// Close both files
fclose(sourceFile);
fclose(destFile);
printf("File copied successfully.\n");
return 0;
}
Storage Class in C
In C, storage classes define the scope (visibility) and lifetime of variables and/or functions within
a program. There are four storage classes in C:
1. Automatic Storage Class (auto)
2. Register Storage Class (register)
3. Static Storage Class (static)
4. External Storage Class (extern)
1. Automatic Storage Class (auto)
• Scope: Local to the block in which it is defined.
• Lifetime: Exists until the block is executed.
• Default: This is the default storage class for all local variables.
#include <stdio.h>
void function() {
auto int x = 10; // auto keyword is optional
printf("Auto variable x = %d\n", x);
}
int main() {
function();
return 0;
}
2. Register Storage Class (register)
• Scope: Local to the block in which it is defined.
• Lifetime: Exists until the block is executed.
• Usage: Suggests that the variable be stored in a CPU register for faster access (modern
compilers often ignore this).
#include <stdio.h>
int main() {
register int x = 10; // suggest storing x in a register
printf("Register variable x = %d\n", x);
return 0;
}
3. Static Storage Class (static)
• Scope: Local to the block in which it is defined (for local variables) or file scope (for
global variables).
• Lifetime: Exists for the entire duration of the program.
• Usage: Preserves the value of the variable between function calls (for local variables) or
restricts the visibility to the file (for global variables).
#include <stdio.h>
void function() {
static int x = 0; // static variable retains its value between calls
x++;
printf("Static variable x = %d\n", x);
}
int main() {
function(); // Output: 1
function(); // Output: 2
function(); // Output: 3
return 0;
}
4. External Storage Class (extern)
• Scope: Global, visible across multiple files.
• Lifetime: Exists for the entire duration of the program.
• Usage: Declares a global variable or function in another file.
File1.c:
#include <stdio.h>
extern int x; // declaration of the external variable
void print_x() {
printf("x = %d\n", x);
}
File2.c:
#include <stdio.h>
int x = 10; // definition of the external variable
int main() {
print_x(); // Output: x = 10
return 0;
}