Unit 5 - Notes
CSE101
Unit 5: Pointers, Dynamic memory allocation and Strings
1. Pointers: Declaration and Initialization
Definition
A pointer is a derived data type in C that stores the memory address of another variable. Unlike normal variables that store values (like int a = 10), pointers store the location where that value is held in memory.
Declaration
The general syntax for declaring a pointer involves the dereference operator (*).
data_type *pointer_name;
- data_type: The type of variable the pointer will point to (e.g.,
int,float,char). - *: Indicates that the variable is a pointer.
Initialization
Initialization involves assigning the address of a variable to the pointer using the address-of operator (&).
int num = 10;
int *ptr; // Declaration
ptr = # // Initialization (ptr now holds the address of num)
2. Types of Pointers
A. Null Pointer
A pointer that is assigned a value of NULL (or 0). It points to nothing. It is good practice to initialize pointers to NULL if they are not assigned a valid address immediately to prevent garbage access.
int *ptr = NULL;
B. Generic (Void) Pointer
A pointer of type void *. It has no associated data type and can hold the address of any type of variable. However, it cannot be dereferenced directly; it must be typecast to a specific type first.
int n = 10;
void *ptr = &n;
printf("%d", *(int*)ptr); // Typecasting required
C. Wild Pointer
A pointer that has been declared but not initialized. It points to an arbitrary (random) memory location. Dereferencing a wild pointer can cause the program to crash or behave unexpectedly.
int *ptr; // Wild pointer
*ptr = 5; // Dangerous!
D. Dangling Pointer
A pointer that points to a memory location that has already been freed (deallocated) or is out of scope.
int *ptr = (int *)malloc(sizeof(int));
free(ptr);
// ptr is now a dangling pointer because the memory it points to is released.
ptr = NULL; // Fix: Assign NULL after freeing.
3. Pointer Expressions and Arithmetic
Pointers can be used in expressions, but their arithmetic rules differ from standard integer arithmetic. Pointer arithmetic is performed relative to the data type size.
Pointer Operators
&(Address-of Operator): Returns the memory address of a variable.- *`` (Dereference/Indirection Operator):** Accesses the value stored at the address held by the pointer.
Valid Operations on Pointers
- Increment (
ptr++): Moves the pointer to the next memory location based on the size of the data type.- If
int *ptris at address 1000 andsizeof(int)is 4,ptr++moves to 1004.
- If
- Decrement (
ptr--): Moves the pointer to the previous memory location. - Addition of Integer (
ptr + n): Moves the pointer forward byn * sizeof(type)bytes. - Subtraction of Integer (
ptr - n): Moves the pointer backward byn * sizeof(type)bytes. - Subtraction of two pointers (
ptr1 - ptr2): Returns the number of elements between the two pointers (provided they point to the same array).
Invalid Operations
- Addition of two pointers (
ptr1 + ptr2). - Multiplication or Division of pointers.
- Bitwise operations on pointers.
4. Passing Pointer to a Function (Call by Reference)
When passing arguments to a function, C uses "Call by Value" by default. To modify the actual arguments in the caller function, we must use pointers (Call by Reference).
Mechanism
- The address of the variable is passed to the function.
- The function parameter is a pointer.
- The function uses the dereference operator (
*) to modify the value at that address.
Example: Swapping Two Numbers
#include <stdio.h>
void swap(int *x, int *y) {
int temp = *x; // Get value at address x
*x = *y; // Put value at y into address x
*y = temp; // Put temp into address y
}
int main() {
int a = 10, b = 20;
swap(&a, &b); // Pass addresses
printf("a = %d, b = %d", a, b); // Output: a = 20, b = 10
return 0;
}
5. Pointers and One-Dimensional Arrays
In C, the name of an array acts as a constant pointer to the first element of the array.
arris equivalent to&arr[0].- Accessing
arr[i]is internally converted by the compiler to*(arr + i).
Accessing Array Elements via Pointers
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // Points to arr[0]
for(int i = 0; i < 5; i++) {
// These three print statements output the same value
printf("%d ", arr[i]); // Array indexing
printf("%d ", *(arr + i)); // Pointer arithmetic using array name
printf("%d ", *(ptr + i)); // Pointer arithmetic using pointer variable
}
6. Dynamic Memory Allocation (DMA)
Static memory allocation (like arrays) reserves memory at compile time. DMA allows allocating memory at runtime using the heap section of memory. These functions are defined in <stdlib.h>.
A. malloc (Memory Allocation)
Allocates a single large block of memory of the specified size.
- Initialization: Contains garbage values.
- Return:
void*(needs casting). ReturnsNULLif allocation fails.
// Syntax: ptr = (cast_type*) malloc(byte_size);
int *ptr = (int*) malloc(5 * sizeof(int));
B. calloc (Contiguous Allocation)
Allocates multiple blocks of memory of the same size.
- Initialization: Initializes all bytes to zero.
- Arguments: Number of blocks, size of each block.
// Syntax: ptr = (cast_type*) calloc(n, element_size);
int *ptr = (int*) calloc(5, sizeof(int));
C. realloc (Re-allocation)
Changes the size of the previously allocated memory block (expands or shrinks). It preserves the previous content.
// Syntax: ptr = realloc(ptr, new_size);
ptr = realloc(ptr, 10 * sizeof(int));
D. free
Deallocates the memory previously allocated by malloc, calloc, or realloc. This is crucial to prevent memory leaks.
// Syntax: free(ptr);
free(ptr);
ptr = NULL; // Good practice
7. Defining and Initializing Strings
A string in C is a one-dimensional array of characters terminated by a null character ('\0').
Declaration and Initialization
-
Using Character Array:
Cchar str[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // Explicit null char str[] = "Hello"; // Implicit null (Compiler adds '\0') -
Using String Pointer:
Cchar *str = "Hello"; // Note: This creates a string literal in read-only memory. // Usually cannot be modified (e.g., str[0] = 'h' might crash).
8. Reading and Writing Strings
Reading Strings
scanf("%s", str);: Reads input until the first whitespace (space, tab, newline). Not suitable for multi-word strings.gets(str);: Reads a line including spaces. (Warning: unsafe, can cause buffer overflow).fgets(str, size, stdin);: The safe standard. Reads up tosize-1characters or new line.
Writing Strings
printf("%s", str);: Standard formatted output.puts(str);: Prints the string followed automatically by a newline.
9. Processing of String and Character Arithmetic
Strings are processed by iterating through the character array until the null terminator (\0) is encountered.
Character Arithmetic
Characters in C are stored as ASCII integer values. We can perform arithmetic on them.
'A' + 1results in'B'.'0'is ASCII 48. Converting a char digit to int:int val = char_digit - '0';.- Converting Lowercase to Uppercase:
char upper = lower - 32;(Since 'a'=97 and 'A'=65).
Example: Manual Length Calculation
char str[] = "Program";
int count = 0;
while (str[count] != '\0') {
count++;
}
printf("Length: %d", count);
10. String Manipulation and Library Functions
The <string.h> library provides built-in functions for string handling.
Common Functions
| Function | Syntax | Description |
|---|---|---|
strlen |
size_t strlen(const char *str) |
Returns the length of the string (excluding \0). |
strcpy |
char* strcpy(char *dest, const char *src) |
Copies content of src to dest. |
strcat |
char* strcat(char *dest, const char *src) |
Concatenates src to the end of dest. |
strcmp |
int strcmp(const char *s1, const char *s2) |
Compares two strings character by character (ASCII). |
strchr |
char* strchr(const char *str, int c) |
Returns pointer to first occurrence of char c in str. |
strcmp Return Values
- 0: Strings are identical.
- > 0: First non-matching char in
s1has a greater ASCII value than ins2. - < 0: First non-matching char in
s1has a lower ASCII value than ins2.
Example Code
#include <stdio.h>
#include <string.h>
int main() {
char s1[20] = "Hello";
char s2[] = "World";
char s3[40];
// Length
printf("Length of s1: %zu\n", strlen(s1));
// Copy
strcpy(s3, s1); // s3 becomes "Hello"
// Concatenate
strcat(s3, " ");
strcat(s3, s2); // s3 becomes "Hello World"
printf("Combined: %s\n", s3);
// Compare
if (strcmp(s1, s2) != 0) {
printf("Strings are different.\n");
}
return 0;
}