Unit5 Notes With Example

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

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;
}

You might also like