&
)*
)malloc
, calloc
, realloc
, and free
void *
(Generic Pointers)NULL
PointerA pointer is a variable that stores the memory address of another variable. Instead of holding a value directly, a pointer “points” to the location in memory where the value is stored.
data_type *pointer_name;
data_type
: The type of data the pointer will point to (e.g., int
, float
, char
).*
: Indicates that the variable is a pointer.pointer_name
: The name of the pointer variable.int x = 10; // An integer variable
int *ptr; // A pointer to an integer
ptr = &x; // Assign the address of x to ptr
Here:
x
is an integer variable with a value of 10
.ptr
is a pointer that stores the address of x
.&
)The &
operator is used to get the memory address of a variable.
int x = 10;
int *ptr = &x; // ptr now holds the address of x
*
)The *
operator is used to access the value stored at the memory address held by the pointer.
int x = 10;
int *ptr = &x;
cout << *ptr << endl; // Output: 10
Here, *ptr
gives the value stored at the address held by ptr
, which is 10
.
Pointer arithmetic allows you to perform arithmetic operations on pointers. The operations are based on the size of the data type the pointer points to.
int arr[] = {10, 20, 30};
int *ptr = arr; // ptr points to the first element of arr
cout << *ptr << endl; // Output: 10
ptr++; // Move to the next integer
cout << *ptr << endl; // Output: 20
ptr++
), it moves to the next element in the array.int
is typically 4 bytes).Arrays and pointers are closely related in C++. The name of an array is essentially a pointer to its first element.
int arr[] = {10, 20, 30};
int *ptr = arr; // ptr points to the first element of arr
cout << *(ptr + 1) << endl; // Output: 20 (second element)
cout << arr[1] << endl; // Output: 20 (same as above)
arr[i]
is equivalent to *(arr + i)
.In C++, a string is an array of characters terminated by a null character ('\0'
). Strings are not a built-in data type in C but are represented using arrays of char
and manipulated using pointers.
char str1[] = "Hello"; // Automatically adds '\0' at the end
char str2[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // Manual null termination
str1
and str2
are both strings containing the word “Hello”.'\0'
) marks the end of the string.Since strings are arrays, you can use pointers to manipulate them.
char *ptr = str1; // ptr points to the first character of str1
cout << *ptr << endl; // Output: H
cout << ptr << endl; // Output: Hello
ptr
points to the first character of the string.*ptr
to access individual characters or ptr
to access the entire string.C++ provides a set of standard library functions for working with strings, declared in <cstring>
.
strlen
: Returns the length of a string.strcpy
: Copies one string to another.strcat
: Concatenates two strings.strcmp
: Compares two strings.Example:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char str1[] = "Hello";
char str2[20];
strcpy(str2, str1); // Copy str1 to str2
strcat(str2, " World"); // Concatenate " World" to str2
cout << str2 << endl; // Output: Hello World
cout << "Length: " << strlen(str2) << endl; // Output: 11
return 0;
}
Write down an implementation for strlen
. </br>
Solution soln
A pointer can also point to another pointer. This is called a pointer to a pointer.
data_type **pointer_name;
int x = 10;
int *ptr = &x; // ptr points to x
int **pptr = &ptr; // pptr points to ptr
cout << **pptr << endl; // Output: 10
pptr
is a pointer to a pointer. It holds the address of ptr
, which in turn holds the address of x
.Passing pointers to functions allows you to modify the original variable directly.
void increment(int *ptr) {
(*ptr)++; // Increment the value at the address held by ptr
}
int main() {
int x = 10;
increment(&x); // Pass the address of x
cout << x << endl; // Output: 11
return 0;
}
void increment_byreference(int *ptr) {
(*ptr)++;
}
void increment_byvalue(int x) {
(x)++;
}
void increment_byreference2(int &x) {
(x)++;
}
int main() {
int x = 10;
increment_byreference(&x); // incremented to 11
increment_byvalue(x); //stay 11
increment_byreference2(x); // incremented to 12
return 0;
}
Functions can also return pointers. Be careful to avoid returning pointers to local variables, as they go out of scope after the function returns.
int* createArray(int size) {
int *arr = (int *)malloc(size * sizeof(int));
return arr;
}
Dynamic memory allocation allows you to allocate memory at runtime using functions like malloc
, calloc
, realloc
, and free
.
malloc
Allocates a block of memory of a specified size.
int *ptr = (int *)malloc(5 * sizeof(int)); // Allocate memory for 5 integers
calloc
Allocates memory and initializes it to zero.
int *ptr = (int *)calloc(5, sizeof(int)); // Allocate and initialize to 0
realloc
Resizes a previously allocated block of memory.
ptr = (int *)realloc(ptr, 10 * sizeof(int)); // Resize to 10 integers
free
Deallocates memory to avoid memory leaks.
free(ptr); // Free the allocated memory
void *
(Generic Pointers)A void *
is a generic pointer that can point to any data type. It is often used in functions that need to handle different types of data.
This section is from https://www.geeksforgeeks.org/void-pointer-c-cpp/
// C Program to demonstrate that a void pointer
// can hold the address of any type-castable type
#include <stdio.h>
int main()
{
int a = 10;
char b = 'x';
// void pointer holds address of int 'a'
void* p = &a;
// void pointer holds address of char 'b'
p = &b;
}
The following program doesn’t compile:
// C Program to demonstrate that a void pointer
// cannot be dereferenced
#include <stdio.h>
int main()
{
int a = 10;
void* ptr = &a;
printf("%d", *ptr);
return 0;
}
Output
Compiler Error: 'void*' is not a pointer-to-object type
The below program demonstrates the usage of a void pointer to store the address of an integer variable. The void pointer is typecasted to an integer pointer and then dereferenced to access the value. The following program compiles and runs fine.
// C program to dereference the void
// pointer to access the value
#include <stdio.h>
int main()
{
int a = 10;
void* ptr = &a;
// The void pointer 'ptr' is cast to an integer pointer
// using '(int*)ptr' Then, the value is dereferenced
// with `*(int*)ptr` to get the value at that memory
// location
printf("%d", *(int*)ptr);
return 0;
}
Output
10
However, in GNU C, it is allowed by considering the size of the void as 1.
The below C program demonstrates the usage of a void pointer to perform pointer arithmetic and access a specific memory location. The following program compiles and runs fine in gcc
.
// C program to demonstrate the usage
// of a void pointer to perform pointer
// arithmetic and access a specific memory location
#include <stdio.h>
int main()
{
// Declare and initialize an integer array 'a' with two elements
int a[2] = { 1, 2 };
// Declare a void pointer and assign the address of array 'a' to it
void* ptr = &a;
// Increment the pointer by the size of an integer
ptr = ptr + sizeof(int);
// The void pointer 'ptr' is cast to an integer pointer
// using '(int*)ptr'. Then, the value is dereferenced
// with `*(int*)ptr` to get the value at that memory location
printf("%d", *(int*)ptr);
return 0;
}
**Output**
2
NULL
PointerA NULL
pointer is a pointer that does not point to any valid memory location. It is often used to indicate that a pointer is not initialized or to mark the end of a data structure (e.g., a linked list).
#include <iostream>
using namespace std;
int main() {
int *ptr = NULL;
if (ptr == NULL) {
cout << "Pointer is NULL" << endl; // Output: Pointer is NULL
} else {
cout << "Pointer is not NULL" << endl;
}
return 0;
}
NULL
if they are not assigned a valid address.NULL
pointer will result in a runtime error (segmentation fault).NULL
and check for NULL
before dereferencing.Pointers, strings, and memory management are fundamental concepts in C++ that allow you to write efficient and flexible programs. By mastering these concepts, you’ll be able to:
void *
.