Interview Question based on Pointers in C and C++
Interview Question based on Pointers in C and C++

Pointers Interview Question on C and C++

Pointers Interview Question on C and C++ : Pointers are one of the most powerful and essential features of C and C++. They allow efficient memory manipulation and direct interaction with hardware. In this blog post, we will explore various types of pointers, their descriptions, and usage examples.

Here are some important pointer-related interview questions, covering NULL pointers, dangling pointers, wild pointers, function pointers, and more. You can use these to write your blog post.

Basic Pointer Questions

1. What is a pointer in C/C++?

A pointer is a variable that stores the memory address of another variable. It allows direct access and manipulation of memory, making it a powerful feature in C and C++.

2. How do you declare and initialize a pointer?

A pointer is declared using the * symbol. Initialization can be done in multiple ways:

int a = 10;        // Normal variable
int* ptr = &a;     // Pointer storing the address of 'a'

Alternatively, you can initialize a pointer to nullptr:

int* ptr = nullptr;  // Pointer initialized to null (C++11 onwards)

3. What happens if you try to dereference an uninitialized pointer?

Dereferencing an uninitialized pointer (wild pointer) leads to undefined behavior, which may cause a segmentation fault or crash. Example:

int* ptr;       // Uninitialized pointer
std::cout << *ptr;  // Undefined behavior (may crash)

4. What is the difference between a pointer and a reference in C++?

FeaturePointerReference
Syntaxint* ptr = &x;int& ref = x;
NullabilityCan be nullptrCannot be null
ReassignmentCan change what it points toCannot be changed after initialization
Memory AddressStores an address explicitlyActs as an alias for the variable

5. How can you print the address stored in a pointer?

You can print the address using cout in C++ or printf in C:

int a = 10;
int* ptr = &a;
std::cout << "Address stored in ptr: " << ptr << std::endl;

Or in C:

printf("Address stored in ptr: %p\n", (void*)ptr);

NULL Pointers

1. What is a NULL pointer?

A NULL pointer is a pointer that does not point to any valid memory location. It is used to indicate that the pointer is not assigned a valid address. In C/C++, it is typically defined as:

#define NULL 0  // In C
#define NULL nullptr  // In C++ (C++11 onwards uses 'nullptr')

Example:

int* ptr = NULL;  // Pointer initialized to NULL

2. Why should you initialize a pointer to NULL?

Initializing a pointer to NULL helps prevent it from becoming a dangling or wild pointer. It makes it easier to check whether a pointer is valid before using it.

Example:

int* ptr = NULL; // Safe initialization
if (ptr == NULL) {
    std::cout << "Pointer is NULL, safe to check before use." << std::endl;
}

3. What happens if you dereference a NULL pointer?

Dereferencing a NULL pointer leads to undefined behavior, which typically results in a segmentation fault (crash).

Example:

int* ptr = NULL;
std::cout << *ptr;  // Crash! Undefined behavior

4. How do you check if a pointer is NULL before using it?

Before dereferencing, always check if a pointer is NULL:

if (ptr != NULL) {
    std::cout << *ptr;  // Safe to use
} else {
    std::cout << "Pointer is NULL, cannot dereference!" << std::endl;
}

In modern C++ (C++11 and later), it’s better to use nullptr:

if (ptr != nullptr) {
    std::cout << *ptr;
}

5. Is NULL the same as 0 in C++?

  • In C, NULL is typically defined as 0.
  • In C++, NULL is still 0, but nullptr (introduced in C++11) is a better alternative because it is strongly typed and prevents accidental type conversions.

Example:

int* p1 = NULL;    // Works, but NULL is just 0
int* p2 = 0;       // Also works, but less readable
int* p3 = nullptr; // Preferred in C++ (strongly typed)

Thus, while NULL and 0 are technically the same in older C++, nullptr is the preferred way in modern C++.

Dangling Pointers

1. What is a dangling pointer?

A dangling pointer is a pointer that refers to a memory location that has been freed, deleted, or gone out of scope. Accessing such a pointer leads to undefined behavior and potential program crashes.

2. How does a dangling pointer occur?

A dangling pointer can occur in several situations:

  1. Deallocation of memory
    • When dynamically allocated memory is freed but the pointer still holds the address.
    int* ptr = new int(10); delete ptr; // Memory is freed std::cout << *ptr; // Dangling pointer access! Undefined behavior
  2. Returning address of a local variable
    • A local variable goes out of scope when a function returns, making the pointer invalid.
    int* getPointer() { int x = 10; return &x; // Returning address of local variable (invalid) } int* ptr = getPointer(); std::cout << *ptr; // Dangling pointer access!
  3. Pointer to an object that goes out of scope
    • When a pointer points to an object that has gone out of scope.
    int* ptr; { int x = 10; ptr = &x; // x goes out of scope after this block } std::cout << *ptr; // Dangling pointer access!

3. How can you prevent dangling pointers?

To avoid dangling pointers, follow these practices:

Set pointers to NULL after freeing memory

int* ptr = new int(10);
delete ptr;
ptr = nullptr;  // Prevents dangling

Avoid returning addresses of local variables

int* getPointer() {
    static int x = 10;  // Static variables persist after function returns
    return &x;
}

Use smart pointers (C++11 and later)

  • Smart pointers (std::unique_ptr and std::shared_ptr) manage memory automatically and prevent dangling pointers.
#include <memory>
std::unique_ptr<int> ptr = std::make_unique<int>(10);

4. What happens if you use a dangling pointer?

Using a dangling pointer leads to undefined behavior, which may cause:

  • Segmentation faults (crashes)
  • Corrupt program data
  • Hard-to-debug memory issues

5. Example of a dangling pointer scenario

#include <iostream>

void dangerousFunction() {
    int* ptr = new int(20);
    delete ptr;  // Memory is freed
    std::cout << *ptr;  // Accessing freed memory (undefined behavior!)
}

int main() {
    dangerousFunction();
    return 0;
}

Solution: Set ptr = nullptr; after delete ptr; to prevent accidental access.

Wild Pointers

1. What is a wild pointer?

A wild pointer is an uninitialized pointer that holds a garbage (random) memory address. Since it does not point to a valid memory location, dereferencing it leads to undefined behavior, including program crashes.

Example of a wild pointer:

int* ptr;  // Wild pointer (uninitialized)
std::cout << *ptr;  // Undefined behavior! Might crash the program

2. How does a wild pointer differ from a dangling pointer?

AspectWild PointerDangling Pointer
DefinitionUninitialized pointer holding garbage valuePointer pointing to memory that has been freed or is out of scope
CauseDeclared but not assigned a valid memory addressMemory deallocation, object going out of scope, or returning a local address
EffectCan point to any random memory locationCan cause undefined behavior when accessed after memory is freed
PreventionAlways initialize pointersSet pointers to nullptr after freeing memory

3. How can you prevent wild pointers?

To avoid wild pointers, follow these best practices:

Initialize pointers before use

int* ptr = nullptr;  // Safe initialization

Allocate memory before dereferencing

int* ptr = new int(10);  // Allocated memory
std::cout << *ptr;  // Safe
delete ptr;
ptr = nullptr;  // Avoids becoming a dangling pointer

Use smart pointers in C++ (C++11 and later)

#include <memory>
std::unique_ptr<int> ptr = std::make_unique<int>(10);  // No need to manually delete

4. How do you detect wild pointers in a program?

Detecting wild pointers can be challenging, but here are some techniques:

Use Valgrind (Linux/Mac) or AddressSanitizer (GCC/Clang)

  • Valgrind helps detect uninitialized memory access.
valgrind --leak-check=full ./program
  • AddressSanitizer (compile with -fsanitize=address) can detect memory issues.

Enable compiler warnings

  • Use -Wall -Wextra -Werror in GCC/Clang to catch uninitialized variables.

Use debug tools like GDB

  • Run the program in GDB (gdb ./program) and check pointer values before dereferencing.

Use assertions to check for nullptr

#include <cassert>
int* ptr = nullptr;
assert(ptr != nullptr);  // This will terminate the program if ptr is NULL

By following these techniques, you can minimize the risk of wild pointers in your program. 🚀

Memory Management and Pointers

1. What is a memory leak in the context of pointers?

A memory leak occurs when dynamically allocated memory is not freed before the pointer to it is lost. This leads to wasted memory, which can degrade system performance and eventually cause the program to crash if memory runs out.

Example of a memory leak:

void memoryLeak() {
    int* ptr = new int(10);  // Memory allocated
    // No delete statement, so memory is never freed (leak)
}

Each time memoryLeak() is called, more memory is allocated but never freed.

2. How do you prevent memory leaks when using dynamic memory allocation?

Always free allocated memory

int* ptr = new int(10);
delete ptr;  // Prevents memory leak
ptr = nullptr;  // Avoids dangling pointer

Use Smart Pointers (C++11 and later)
Smart pointers automatically manage memory, preventing leaks.

#include <memory>
std::unique_ptr<int> ptr = std::make_unique<int>(10);  // No need to delete

Track allocations and deallocations carefully
Use tools like Valgrind, AddressSanitizer, or GDB to detect leaks.

Follow the Rule of Thumb:
Every new should have a delete, and every malloc() should have a free().

3. What is the purpose of malloc() and free() in C?

  • malloc(size_t size): Allocates size bytes of memory from the heap and returns a pointer to it. The memory is not initialized.
  • free(void* ptr): Frees the dynamically allocated memory, making it available for reuse.

Example:

#include <stdlib.h>
int* ptr = (int*)malloc(sizeof(int) * 5);  // Allocates memory for 5 integers
free(ptr);  // Frees the allocated memory

4. What is the difference between malloc() and new in C++?

Featuremalloc() (C)new (C++)
Memory AllocationAllocates raw memoryAllocates memory and calls constructor
InitializationNo initializationInitializes objects if applicable
Return Typevoid* (requires casting)Returns specific type (no casting needed)
Usageint* p = (int*)malloc(sizeof(int));int* p = new int;
Freeing Memoryfree(ptr);delete ptr;

Use new in C++ instead of malloc() for object-oriented programming, as it automatically calls constructors.


5. What happens if you call free() on a NULL pointer?

  • Calling free(NULL) is safe and has no effect in C/C++.
  • The C standard guarantees that free(NULL); does nothing.

Example:

int* ptr = NULL;
free(ptr);  // Safe, no effect

6. What happens if you call delete twice on the same pointer?

  • Calling delete twice on the same pointer causes undefined behavior, which may result in a crash or memory corruption.

Example of double delete (Undefined Behavior!):

int* ptr = new int(10);
delete ptr;  // First delete (valid)
delete ptr;  // Second delete (undefined behavior!)

Solution: Set the pointer to nullptr after deleting it.

int* ptr = new int(10);
delete ptr;
ptr = nullptr;  // Prevents double delete

🚀 By following best practices, you can avoid memory leaks and undefined behavior in your programs!

Pointer Arithmetic

1. What operations can be performed on pointers?

Pointers support several operations:

Assignment: Assign one pointer to another of the same type.

int a = 10;
int* p1 = &a;
int* p2 = p1;  // Assigning one pointer to another

Dereferencing (*): Access the value stored at the pointer’s address.

std::cout << *p1;  // Prints value of 'a' (10)

Pointer Arithmetic:

  • Increment (ptr++), decrement (ptr--)
  • Addition (ptr + n), subtraction (ptr - n)
  • Subtracting two pointers (ptr1 - ptr2)

Comparison (==, !=, >, <): Compare pointer addresses.

if (p1 == p2) { std::cout << "Same address"; }

2. What happens when you increment a pointer?

When you increment a pointer (ptr++), it moves to the next memory location based on its data type size.

Example:

int arr[3] = {10, 20, 30};
int* ptr = arr;  // Points to arr[0]

ptr++;  // Moves to arr[1], not just 1 byte but sizeof(int) bytes
std::cout << *ptr;  // Prints 20

📌 For an int*, ptr++ increases the address by sizeof(int) (usually 4 bytes).

3. How do pointer arithmetic operations depend on the data type?

Pointer arithmetic is based on the size of the data type:

Data TypeSize (sizeof(type))ptr++ moves by
char*1 byte1 byte
int*4 bytes (typical)4 bytes
double*8 bytes8 bytes

Example:

char c = 'A';
char* p1 = &c;
p1++;  // Moves by 1 byte

double d = 3.14;
double* p2 = &d;
p2++;  // Moves by 8 bytes (on most systems)

4. What is pointer subtraction?

Pointer subtraction (ptr1 - ptr2) finds the distance (number of elements) between two pointers pointing to the same array.

Example:

int arr[] = {10, 20, 30, 40, 50};
int* p1 = &arr[1];  // Points to 20
int* p2 = &arr[4];  // Points to 50

std::cout << (p2 - p1);  // Output: 3 (elements apart)

📌 Formula: (p2 - p1) = (Address2 - Address1) / sizeof(type)

5. Why can’t you add two pointers?

Adding two pointers (ptr1 + ptr2) has no logical meaning because:

  • A pointer stores a memory address, and adding two addresses doesn’t make sense.
  • Pointer arithmetic is defined in terms of element sizes, not memory locations.

Invalid:

int* p1, *p2;
int* p3 = p1 + p2;  // Error: Addition of pointers is not allowed

Allowed Operations:

  • Pointer + Integer (ptr + n moves the pointer n elements ahead)
  • Pointer – Pointer (finds distance between elements)

🚀 By understanding these operations, you can use pointers efficiently in C/C++!

Function Pointers

1. What is a function pointer?

A function pointer is a pointer that stores the address of a function, allowing you to call the function indirectly.

✔ Functions in C/C++ are stored in memory, and their addresses can be assigned to pointers.

✔ Function pointers are useful for callback functions, dynamic function selection, and polymorphism in C.

2. How do you declare and use a function pointer?

Declaration:

returnType (*pointerName)(parameterTypes);

Example: Using a Function Pointer

#include <iostream>

// Function to be pointed to
void hello() {
    std::cout << "Hello, World!\n";
}

int main() {
    void (*funcPtr)();  // Function pointer declaration
    funcPtr = hello;  // Assign function address
    funcPtr();  // Call function through pointer

    return 0;
}

📌 No need for & before function name (hello) because function names decay into pointers.

3. What is a use case for function pointers?

Function pointers are commonly used in:

Callback functions (e.g., signal handlers, event handling)
Dynamic function selection (e.g., strategy patterns)
Jump tables (efficient switch-case alternatives)
Sorting with custom comparison functions (qsort() in C)

Example: Function Pointer in qsort()

#include <stdio.h>
#include <stdlib.h>

// Comparison function for sorting in ascending order
int compare(const void* a, const void* b) {
    return (*(int*)a - *(int*)b);
}

int main() {
    int arr[] = {4, 2, 9, 1, 5};
    int size = sizeof(arr) / sizeof(arr[0]);

    qsort(arr, size, sizeof(int), compare);  // Function pointer as argument

    for (int i = 0; i < size; i++)
        printf("%d ", arr[i]);  // Output: 1 2 4 5 9

    return 0;
}

📌 compare is passed as a function pointer to qsort() for sorting.

A callback function is a function passed as an argument to another function. This allows for dynamic function execution.

Example: Function Pointer as a Callback

#include <iostream>

// Callback function
void printMessage(const std::string& msg) {
    std::cout << msg << std::endl;
}

// Function that takes a function pointer as a parameter
void executeCallback(void (*callback)(const std::string&)) {
    callback("Callback executed!");
}

int main() {
    executeCallback(printMessage);
    return 0;
}

📌 The executeCallback() function calls the function passed to it dynamically.

5. Can a function return a pointer to another function?

Yes! A function can return a pointer to another function, often used in function factories.

Example: Returning a Function Pointer

#include <iostream>

// Functions
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }

// Function returning a pointer to another function
int (*getOperation(char op))(int, int) {
    return (op == '+') ? add : subtract;
}

int main() {
    auto func = getOperation('+');  // Get function pointer
    std::cout << func(5, 3);  // Output: 8
    return 0;
}

📌 getOperation() returns a pointer to either add or subtract, allowing dynamic function selection.

🚀 Function pointers are powerful tools for dynamic behavior in C/C++!

Pointers and Arrays

1. What is the relationship between arrays and pointers in C?

  • In C, an array name acts as a pointer to its first element.
  • The expression arr is equivalent to &arr[0].
  • The name of an array cannot be modified (it’s a constant pointer), but a pointer variable can be used to traverse an array.

Example:

int arr[] = {10, 20, 30};
int* ptr = arr;  // Equivalent to int* ptr = &arr[0];
printf("%d", *ptr);  // Output: 10

2. How do you pass an array to a function using pointers?

Arrays are always passed as pointers to functions to avoid copying large amounts of data.

Example: Passing an Array Using Pointers

#include <stdio.h>

void printArray(int* arr, int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
}

int main() {
    int numbers[] = {1, 2, 3, 4, 5};
    printArray(numbers, 5);  // Passing array as a pointer
    return 0;
}

📌 The function receives int* arr, not int arr[], since both are equivalent.

3. What happens if you increment an array name?

  • You cannot increment an array name (arr++) because it is a constant pointer (arr is fixed at &arr[0]).
  • However, you can increment a pointer variable that points to an array.

Example:

int arr[] = {10, 20, 30};
int* ptr = arr;  // Pointer variable

ptr++;  // Valid: Moves to the next element
arr++;  // ❌ Invalid: Compiler error (array name is constant)

4. How do you dynamically allocate memory for an array?

  • Use malloc() or calloc() in C.
  • Use new[] in C++.
  • Always free memory using free() in C or delete[] in C++.

Example in C (malloc)

#include <stdio.h>
#include <stdlib.h>

int main() {
    int* arr = (int*)malloc(5 * sizeof(int));  // Allocate memory for 5 integers
    if (!arr) { return 1; }  // Check for allocation failure

    for (int i = 0; i < 5; i++) {
        arr[i] = i * 10;
        printf("%d ", arr[i]);
    }

    free(arr);  // Free allocated memory
    return 0;
}

Example in C++ (new)

#include <iostream>

int main() {
    int* arr = new int[5];  // Allocate memory for 5 integers
    for (int i = 0; i < 5; i++) {
        arr[i] = i * 10;
        std::cout << arr[i] << " ";
    }

    delete[] arr;  // Free allocated memory
    return 0;
}

📌 Always use free() (C) or delete[] (C++) to prevent memory leaks.

5. How can you use pointers to iterate over an array?

A pointer can traverse an array just like an index.

Example: Using Pointer Arithmetic

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int* ptr = arr;  // Points to arr[0]

    for (int i = 0; i < 5; i++) {
        printf("%d ", *(ptr + i));  // Access array using pointer arithmetic
    }

    return 0;
}

📌 ptr + i moves the pointer by i elements (not bytes).

🚀 Understanding pointers with arrays makes memory management and performance optimization easier in C/C++!

Pointers and Structures

1. How do you declare a pointer to a structure?

A pointer to a structure is declared using the struct keyword followed by an asterisk (*).

Example:

#include <stdio.h>

struct Student {
    int id;
    char name[20];
};

int main() {
    struct Student s1 = {101, "Alice"};
    struct Student* ptr = &s1;  // Pointer to structure

    printf("ID: %d, Name: %s\n", ptr->id, ptr->name);
    return 0;
}

📌 ptr is a pointer to struct Student and holds the address of s1.

2. What is the -> operator used for in pointers to structures?

  • The arrow operator (->) is used to access structure members through a pointer.
  • It is a shorthand for (*pointer).member.

Example:

ptr->id   // Equivalent to (*ptr).id
ptr->name // Equivalent to (*ptr).name

Using -> avoids excessive parentheses and improves readability.

3. How can you allocate memory for a structure dynamically?

  • Use malloc() in C.
  • Use new in C++.

Example in C (Using malloc())

#include <stdio.h>
#include <stdlib.h>

struct Student {
    int id;
    char name[20];
};

int main() {
    struct Student* ptr = (struct Student*)malloc(sizeof(struct Student));
    if (!ptr) { return 1; }  // Check if memory allocation was successful

    ptr->id = 102;
    snprintf(ptr->name, sizeof(ptr->name), "Bob");

    printf("ID: %d, Name: %s\n", ptr->id, ptr->name);

    free(ptr);  // Free allocated memory
    return 0;
}

Example in C++ (Using new)

#include <iostream>

struct Student {
    int id;
    std::string name;
};

int main() {
    Student* ptr = new Student;
    ptr->id = 103;
    ptr->name = "Charlie";

    std::cout << "ID: " << ptr->id << ", Name: " << ptr->name << std::endl;

    delete ptr;  // Free allocated memory
    return 0;
}

📌 Always use free() in C and delete in C++ to prevent memory leaks.

4. Can a structure contain a pointer to itself?

Yes, a structure can contain a pointer to itself, which is useful for linked lists, trees, and other dynamic data structures.

Example: Self-referential Structure (Linked List Node)

#include <stdio.h>

struct Node {
    int data;
    struct Node* next;  // Pointer to the next node (same structure type)
};

int main() {
    struct Node node1, node2;
    node1.data = 10;
    node2.data = 20;
    node1.next = &node2;  // Linking nodes

    printf("Node 1 Data: %d, Node 2 Data: %d\n", node1.data, node1.next->data);
    return 0;
}

📌 This is the foundation of linked lists!

5. What is the difference between . and -> in structure access?

OperatorUsed withExampleMeaning
. (dot)Structure variables1.idAccess member of a structure variable
-> (arrow)Pointer to structureptr->idAccess member through a structure pointer

Example Demonstrating Both:

#include <stdio.h>

struct Student {
    int id;
    char name[20];
};

int main() {
    struct Student s1 = {104, "David"};
    struct Student* ptr = &s1;

    printf("Using . operator: ID = %d, Name = %s\n", s1.id, s1.name);
    printf("Using -> operator: ID = %d, Name = %s\n", ptr->id, ptr->name);

    return 0;
}

📌 Use . for normal variables and -> for pointers!

Smart Pointers (C++ Specific)

1. What are smart pointers in C++?

Smart pointers are RAII-based (Resource Acquisition Is Initialization) wrappers around raw pointers that automatically manage memory in C++. They reside in the <memory> header and help prevent memory leaks and dangling pointers.

Types of Smart Pointers in C++:

  • std::unique_ptr → Exclusive ownership (cannot be shared).
  • std::shared_ptr → Shared ownership (reference counting).
  • std::weak_ptr → Weak reference (no ownership, avoids circular references).

📌 Smart pointers automatically deallocate memory when they go out of scope!

2. What is std::unique_ptr and how does it work?

  • std::unique_ptr allows only one owner of the resource.
  • It deletes the resource automatically when it goes out of scope.
  • Cannot be copied, but can be moved to transfer ownership.

Example: Using std::unique_ptr

#include <iostream>
#include <memory>  // Include <memory> for smart pointers

class Example {
public:
    Example() { std::cout << "Constructor Called\n"; }
    ~Example() { std::cout << "Destructor Called\n"; }
};

int main() {
    std::unique_ptr<Example> ptr = std::make_unique<Example>();  // Creates a unique_ptr

    // std::unique_ptr<Example> ptr2 = ptr; ❌ (Copying not allowed)
    std::unique_ptr<Example> ptr2 = std::move(ptr);  // ✅ Transfer ownership

    return 0;  // Destructor is called when ptr2 goes out of scope
}

📌 Best choice when you want sole ownership of a resource.

3. How does std::shared_ptr differ from std::unique_ptr?

std::shared_ptr allows multiple pointers to share ownership of the same object.
✅ Uses reference counting: The resource is deleted when the last shared_ptr goes out of scope.

Example: Using std::shared_ptr

#include <iostream>
#include <memory>

class Example {
public:
    Example() { std::cout << "Constructor Called\n"; }
    ~Example() { std::cout << "Destructor Called\n"; }
};

int main() {
    std::shared_ptr<Example> ptr1 = std::make_shared<Example>();  // Shared ownership
    std::shared_ptr<Example> ptr2 = ptr1;  // ptr2 shares ownership

    std::cout << "Reference Count: " << ptr1.use_count() << std::endl;

    return 0;  // Destructor is called when the last reference goes out of scope
}

📌 Best choice when multiple parts of the program need shared access to a resource.

4. What is a weak pointer (std::weak_ptr)?

std::weak_ptr is a non-owning reference to a std::shared_ptr.
✅ Used to prevent circular references (memory leaks) in shared pointers.

Why Use std::weak_ptr?

  • If two std::shared_ptrs reference each other, their reference count never reaches zero, causing a memory leak (circular reference).
  • std::weak_ptr helps break this cyclic dependency.

Example: Preventing Circular References

#include <iostream>
#include <memory>

class B;
class A {
public:
    std::shared_ptr<B> b_ptr;
    ~A() { std::cout << "A Destroyed\n"; }
};

class B {
public:
    std::weak_ptr<A> a_ptr;  // Use weak_ptr to prevent circular reference
    ~B() { std::cout << "B Destroyed\n"; }
};

int main() {
    std::shared_ptr<A> a = std::make_shared<A>();
    std::shared_ptr<B> b = std::make_shared<B>();

    a->b_ptr = b;
    b->a_ptr = a;  // Using weak_ptr prevents a memory leak

    return 0;  // Objects are correctly deleted
}

📌 Best choice when objects should not keep each other alive indefinitely.

5. How do smart pointers help prevent memory leaks?

Automatic Resource Management → Smart pointers ensure allocated memory is freed automatically.
Exception Safety → If an exception occurs, smart pointers automatically clean up resources.
No Need for Manual delete → Reduces the risk of forgetting to free memory.
Prevents Dangling Pointers → Smart pointers go out of scope gracefully, preventing use-after-free errors.
Avoids Circular Referencesstd::weak_ptr prevents memory leaks due to cyclic dependencies in shared pointers.

Example: Preventing Memory Leaks

#include <iostream>
#include <memory>

class Example {
public:
    Example() { std::cout << "Resource Acquired\n"; }
    ~Example() { std::cout << "Resource Released\n"; }
};

void create() {
    std::shared_ptr<Example> ptr = std::make_shared<Example>();
}  // Object is automatically deleted when function exits

int main() {
    create();
    std::cout << "End of main\n";
    return 0;
}

No need for delete, memory is freed when ptr goes out of scope!

1. NULL Pointer

A NULL pointer is a pointer that is explicitly assigned NULL or nullptr (in C++11 and later). It does not point to any valid memory location.

Example:

int* ptr = NULL; // C-style null pointer
int* ptr2 = nullptr; // Modern C++ null pointer

2. Void Pointer

A void pointer (generic pointer) can hold the address of any data type but requires explicit type casting before dereferencing.

Example:

void* ptr;
int x = 10;
ptr = &x; // Storing address of an integer

3. Dangling Pointer

A dangling pointer occurs when a pointer points to memory that has been freed or deleted.

Example:

int* ptr = new int(5);
delete ptr; // ptr is now dangling

4. Wild Pointer

A wild pointer is an uninitialized pointer that holds a garbage value, leading to unpredictable behavior.

Example:

int* ptr; // Uninitialized, wild pointer

5. Generic Pointer

A generic pointer (same as void pointer) can store the address of any variable and can be typecast accordingly.

Example:

void* ptr;
int x = 10;
ptr = &x;
int* intPtr = (int*)ptr;

6. Near Pointer (Legacy – 16-bit systems)

A near pointer is a 16-bit pointer that accesses memory within the current segment.

Example: (Only valid in 16-bit compilers)

int near *ptr; // Supported in old MS-DOS compilers

7. Far Pointer (Legacy – 16-bit systems)

A far pointer is a 32-bit pointer with a segment and offset, used for accessing memory beyond the current segment.

Example: (Only valid in 16-bit compilers)

int far *ptr;

8. Huge Pointer (Legacy – 16-bit systems)

A huge pointer is similar to a far pointer but ensures a unique physical address.

Example: (Only valid in 16-bit compilers)

int huge *ptr;

9. Function Pointer

A function pointer stores the address of a function and can be used to call the function dynamically.

Example:

#include <iostream>
void display(int x) { std::cout << "Value: " << x << std::endl; }
int main() {
    void (*funcPtr)(int) = &display;
    funcPtr(10);
}

10. Array Pointer

A pointer to an array points to the first element of an array.

Example:

int arr[5] = {1, 2, 3, 4, 5};
int* ptr = arr;

11. Pointer to Pointer

A pointer to pointer stores the address of another pointer.

Example:

int x = 10;
int* ptr = &x;
int** ptr2 = &ptr;

12. Smart Pointer (C++11+)

A smart pointer manages memory automatically, preventing memory leaks.

Example:

#include <memory>
std::unique_ptr<int> ptr = std::make_unique<int>(42);

13. Const Pointer

A constant pointer cannot change the address it is pointing to.

Example:

int x = 10;
int* const ptr = &x; // Address is constant

14. Pointer to Const

A pointer to a constant points to a constant value and prevents modification.

Example:

const int x = 10;
const int* ptr = &x; // Cannot modify *ptr

15. Const Pointer to Const

A constant pointer to a constant means both the address and the value cannot be modified.

Example:

const int x = 10;
const int* const ptr = &x; // Neither value nor address can be changed

16. This Pointer (C++ Specific)

A this pointer is available in non-static member functions and points to the object that invoked the function.

Example:

class MyClass {
public:
    void display() { std::cout << this; }
};

17. nullptr Pointer (C++11+)

nullptr is a modern way to represent null pointers in C++.

Example:

int* ptr = nullptr;
Spread the knowledge with embedded prep
Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *