Category: C++ Pointers

https://zain.sweetdishy.com/wp-content/uploads/2026/02/Pointers.png

  • Smart Pointers in C++

    smart pointer is a class template that wraps around a raw pointer. It is used in memory management to clear the dynamically allocated memory automatically when it is no longer needed. This prevents memory leaks and dangling pointers. They are implemented as templates in the Standard Template Library (STL) (<memory> header).

    Memory Leak: In C++, we need to manually clear the dynamically allocated memory. Memory leak occurs when the dynamically allocated memory is not cleared.
    Dangling Pointer: It is a pointer that points to the memory address that has been cleared earlier but it still pointing to that deallocated memory address.

    Here is an example of memory leak and dangling pointer where the ptr pointer causes a memory leak and the ptr2 pointer becomes a dangling pointer.

    #include <iostream>usingnamespace std;intmain(){int*ptr1 =newint(42);// allocating memory
        cout <<"ptr1 pointer Value: "<<*ptr1 << endl;// Here memory leak occurs as we have// not freed the allocated memoryint*ptr2 =newint(100);// allocating memorydelete ptr2;// clearing the memory// accessing freed memory
        cout <<"ptr2 pointer value: "<<*ptr2 << endl;// dangling pointerreturn0;}

    The output of the above code is as follows −

    ptr1 pointer Value: 42
    ptr2 pointer value: 1465330567
    

    Types of Smart Pointers

    Smart pointers are of 4 types that are mentioned below. You need to use <memory> header to use these smart pointers −

    The auto_ptr Pointer

    The auto_ptr is a type of smart pointer that automatically manages memory. It is now deprecated since C++11, and removed in C++17 as it uses copy assignments operator to transfer ownership automatically without warning and the original pointer becomes null unexpectedly. This leads to unexpected null pointer access and program can crash.

    Here is a simple example of auto_ptr where we are printing the value of ptr1 and ptr2. It will show a warning in the output as it has been deprecated −

    #include <iostream>#include <memory>usingnamespace std;intmain(){
        auto_ptr<int>ptr1(newint(100));
        cout <<"ptr1 value: "<<*ptr1 << endl;
    
        auto_ptr<int> ptr2 = ptr1;
        cout <<"ptr2 value: "<<*ptr2 << endl;return0;}

    The output of the above code is as follows. As we can see here it gives a warning that auto_pointer has been deprecated −

    main.cpp: In function 'int main()':
    main.cpp:7:5: warning: 'template<class> class std::auto_ptr' is deprecated: use 
        'std::unique_ptr' instead [-Wdeprecated-declarations]
        7 |     auto_ptr<int> ptr1(new int(100));
    
    ptr1 value: 100
    ptr2 value: 100
    

    The unique_ptr Pointer

    The unique_ptr is a smart pointer that owns only one object at a time. It does not copy the pointers from one pointer to other. It transfers its ownership using std::move() function and automatically deletes the memory when the pointer goes out of scope. It solves the problem of auto_ptr and prevent memory leaks. You can use unique_ptr for single ownership.

    Below is an example of unique_ptr where the pointer ptr1 transfers its ownership to pointer ptr2 to print the pointer value −

    #include <iostream>#include <memory>usingnamespace std;intmain(){
        unique_ptr<int> ptr1 =make_unique<int>(200);
        cout <<"ptr1 value: "<<*ptr1 << endl;
    
        unique_ptr<int> ptr2 =move(ptr1);
        cout <<"ptr2 value: "<<*ptr2 << endl;return0;}

    The output of the above code is as follows:

    ptr1 value: 200
    ptr2 value: 200
    

    The shared_ptr Pointer

    shared_ptr is a smart pointer that allows multiple pointers to share ownership of the same object using reference counting, unlike unique_ptr where only one pointer can have the ownership of an object.

    It maintains a reference count to keep a track of number of pointers sharing one object. The reference count is decreased when a shared_ptr is destroyed and the object is automatically deleted when count reaches zero. You can use shared_ptr when you need multiple owners of the same object.

    Here is an example of shared_ptr where both the pointers share the same object −

    #include <iostream>#include <memory>usingnamespace std;intmain(){
        shared_ptr<int> ptr1 =make_shared<int>(300);
        cout <<"ptr1 value: "<<*ptr1 << endl;
        cout <<"Reference count: "<< ptr1.use_count()<< endl;
    
        shared_ptr<int> ptr2 = ptr1;// Both can access the object
        cout <<"\nAfter sharing:"<< endl;
        cout <<"ptr1 value: "<<*ptr1 << endl;
        cout <<"ptr2 value: "<<*ptr2 << endl;
        cout <<"Reference count: "<< ptr1.use_count()<< endl;return0;}

    The output of the above code is as follows −

    ptr1 value: 300
    Reference count: 1
    
    After sharing:
    ptr1 value: 300
    ptr2 value: 300
    Reference count: 2
    

    The weak_ptr Pointer

    weak_ptr is a non-owning pointer to an object. Unlike shared_ptr, it does not increase the reference count of an object, and it can detect if the object has been destroyed. You can access the object using weak_ptr, but first you must lock the weak_ptr. By locking you get a temporary shared_ptr. It is used to avoid the circular dependency between shared_ptr objects.

    Here is an example of accessing an object value 400 using weak_ptr observer −

    #include <iostream>#include <memory>usingnamespace std;intmain(){
        shared_ptr<int> owner =make_shared<int>(400);
        weak_ptr<int> observer = owner;
        cout <<"shared_ptr reference count: "<< owner.use_count()<< endl;// Lock to use weak_ptrif(auto locked = observer.lock()){
            cout <<"Object value: "<<*locked << endl;}
        owner.reset();
        cout << endl;return0;}

    The output of the above code is as follows −

    shared_ptr reference count: 1
    Object value: 400
    

    Pointer vs Smart Pointer

    The following table differentiates between a pointer and a smart pointer −

    PointerSmart Pointer
    A pointer stores memory address of another variable or object.A smart pointer is a class template that wraps around a raw pointer and used for automatic memory management.
    Manually new and delete is called to allocate and deallocate memory.It uses RAII(Resource Acquisition is Initialization) principles to automatically manage memory for allocation and deallocation.
    It creates chances of memory leak and dangling pointers.No risk of memory leaks or dangling pointers.
    There is no feature to track the numbers of pointers pointing to an object.Here, shared_ptr maintains a reference counter to track the number of pointers pointing to the same object.
    It is not destroyed when it goes out of its scope.It gets automatically destroyed when it goes out of scope.

    Conclusion

    Smart pointers in C++ help in automatic memory management that solves the problem of memory leak and dangling pointers. There are four types of smart pointers: auto_ptrunique_ptrshared_ptr, and weak_ptr, out of which the auto_ptr has been deprecated.

  • C++ Modify Pointers

    In C++ programming, a pointer is a variable that stores the memory address of another variable. Instead of holding a data value directly, a pointer holds the memory location of the value.

    What is Modifying Pointers in C++?

    Modifying the pointer value in C++ refers to the process of changing the memory address or changing the value stored at the memory address the pointer is pointing to.

    Approach to Modify Pointers

    Begin with declaring a pointer variable and initializing it. To modify the pointer’s value, assign a new address to it. If using dynamic memory, allocate new memory using new and assign its address to the pointer. After modifying the pointer, you can dereference it to access or modify the value at the new address.

    If you allocate memory dynamically, ensure to release it using delete to prevent memory leaks.

    Example of Modifying Pointers

    Here’s a simple example illustrating the modification of the pointers values −

    #include <iostream>usingnamespace std;intmain(){int var1 =10;int var2 =20;int* ptr =&var1;// ptr points to var1
       cout <<"Value pointed by ptr: "<<*ptr << endl; 
    
       ptr =&var2;// Modify ptr to point to var2
       cout <<"Value pointed by ptr after modification: "<<*ptr << endl;// Dynamic memory allocationint* dynamicPtr =newint(30);
       ptr = dynamicPtr;// Modify ptr to point to dynamic memory
       cout <<"Value pointed by ptr after dynamic allocation: "<<*ptr << endl;// Clean up dynamic memorydelete dynamicPtr;return0;}

    Output

    Value pointed by ptr: 10
    Value pointed by ptr after modification: 20
    Value pointed by ptr after dynamic allocation: 30
    

    Explanation

    • Firstly, we declared (var1 and var2) and initialized the variable with values 10 and 20.
    • Then declared the pointer named ptr, which holds the address of an integer, var1 using the address-of operator (&).
    • *ptr, the value at the address stored in ptr is accessed using the dereference operator (*).
    • ptr = &var2; The pointer ptr is modified to point to var2. Now, when dereferenced, it will access the value of var2, which is 20, so this prints 20.
    • Now for Dynamic Memory Allocation, int* dynamicPtr = new int(30); Memory is dynamically allocated using new and initialized to 30, Where the address of this memory is stored in the pointer dynamicPtr.
    • ptr = dynamicPtr; in this ptr is modified to point to the dynamically allocated memory (dynamicPtr). When dereferenced, it will print 30.
    • delete dynamicPtr; This is used to prevent memory leaks.
  • C++ Dereferencing

    In C++, dereferencing is the process that helps in accessing the value that a pointer points to. Where pointers store the memory address of that particular value. To access or modify the value stored at that address, you can use the dereference operator denoted by (*).

    Dereferencing to Read a Value

    Here is the syntax to access the value, which is stored at the address the pointer points to −

    Type value =*pointer;// Gets the value at the address pointed to by the pointer

    Dereferencing to Modify a Value

    Syntax of dereference operator to modify the value at the address the pointer points to −

    *pointer = newValue;// Sets the value at the address pointed to by the pointer

    Example of C++ Dereferencing

    Heres a simple example illustrating dereferencing in C++ −

    #include <iostream>usingnamespace std;intmain(){int number =42;// A normal integer variableint* ptr =&number;// Pointer that holds the address of 'number'// Dereferencing to read the value
       cout <<"Original Value: "<<*ptr << endl;// Dereferencing to modify the value*ptr =100;  
       cout <<"Modified Value: "<< number << endl;return0;}

    Output

    Original Value: 42
    Modified Value: 100
    

    Explanation

    • Firstly, we declared an integer variable named number and initialized it with the value 42.
    • Declared a pointer ptr of data type integer. The pointer is assigned the address of the number using the address-of operator &. which means ptr will point to the location of the memory address of a number.
    • Now, we used the dereference operator to access the value stored at the address pointed to by ptr.
    • *ptr = 100; This line uses the dereference operator again, but this time to assign a new value.

    References vs Dereference

    ReferencesDereference
    DefinitionReference is a variable for another variable, which allows you to access or modify the original variable without using its name directly.Dereferencing is the process of accessing the value stored at the memory address held by a pointer.
    Symbol& (used in declaration)* (used in expression)
    SyntaxdataType& referenceName = existingVariable;dataType pointerVariable = *pointerName;

    Example Showing both Reference and Dereference

    Heres an example illustrating both reference and dereference in a code.

    #include <iostream>usingnamespace std;intmain(){int number =42;// Pointer holding the address of 'number'int* ptr =&number;// Reference to 'number'int& ref = number;// Using pointer to read the value (dereferencing ptr)
       cout <<"Original Value (pointer): "<<*ptr << endl;// Using reference to read the value
       cout <<"Original Value (reference): "<< ref << endl;// Modifying the value through the pointer (dereferencing ptr)*ptr =100;  
       cout <<"Modified Value (pointer): "<< number << endl;  
       cout <<"Modified Value (reference): "<< ref << endl;// Modifying the value through the reference
       ref =200;  
       cout <<"Modified Value (reference): "<< number << endl;  
       cout <<"Modified Value (pointer): "<<*ptr << endl;return0;}

    Output

    Original Value (pointer): 42
    Original Value (reference): 42
    Modified Value (pointer): 100
    Modified Value (reference): 100
    Modified Value (reference): 200
    Modified Value (pointer): 200
  • C++ Pointers

    C++ pointers are easy and fun to learn. Some C++ tasks are performed more easily with pointers, and other C++ tasks, such as dynamic memory allocation, cannot be performed without them.

    As you know every variable is a memory location and every memory location has its address defined which can be accessed using ampersand (&) operator which denotes an address in memory. Consider the following which will print the address of the variables defined −

    #include <iostream>usingnamespace std;intmain(){int  var1;char var2[10];
    
       cout <<"Address of var1 variable: ";
       cout <<&var1 << endl;
    
       cout <<"Address of var2 variable: ";
       cout <<&var2 << endl;return0;}

    When the above code is compiled and executed, it produces the following result −

    Address of var1 variable: 0xbfebd5c0
    Address of var2 variable: 0xbfebd5b6
    

    What are Pointers?

    pointer is a variable whose value is the address of another variable. Like any variable or constant, you must declare a pointer before you can work with it. The general form of a pointer variable declaration is −

    type *var-name;

    Here, type is the pointer’s base type; it must be a valid C++ type and var-name is the name of the pointer variable. The asterisk you used to declare a pointer is the same asterisk that you use for multiplication. However, in this statement the asterisk is being used to designate a variable as a pointer. Following are the valid pointer declaration −

    int*ip;// pointer to an integerdouble*dp;// pointer to a doublefloat*fp;// pointer to a floatchar*ch     // pointer to character

    The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the same, a long hexadecimal number that represents a memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to.

    Using Pointers in C++

    There are few important operations, which we will do with the pointers very frequently. (a) We define a pointer variable. (b) Assign the address of a variable to a pointer. (c) Finally access the value at the address available in the pointer variable. This is done by using unary operator * that returns the value of the variable located at the address specified by its operand. Following example makes use of these operations −

    #include <iostream>usingnamespace std;intmain(){int  var =20;// actual variable declaration.int*ip;// pointer variable 
    
       ip =&var;// store address of var in pointer variable
    
       cout <<"Value of var variable: ";
       cout << var << endl;// print the address stored in ip pointer variable
       cout <<"Address stored in ip variable: ";
       cout << ip << endl;// access the value at the address available in pointer
       cout <<"Value of *ip variable: ";
       cout <<*ip << endl;return0;}

    When the above code is compiled and executed, it produces result something as follows −

    Value of var variable: 20
    Address stored in ip variable: 0xbfc601ac
    Value of *ip variable: 20
    

    Pointers in C++

    Pointers have many but easy concepts and they are very important to C++ programming. There are following few important pointer concepts which should be clear to a C++ programmer −

    Sr.NoConcept & Description
    1Null PointersC++ supports null pointer, which is a constant with a value of zero defined in several standard libraries.
    2Pointer ArithmeticThere are four arithmetic operators that can be used on pointers: ++, –, +, –
    3Pointers vs ArraysThere is a close relationship between pointers and arrays.
    4Array of PointersYou can define arrays to hold a number of pointers.
    5Pointer to PointerC++ allows you to have pointer on a pointer and so on.
    6Passing Pointers to FunctionsPassing an argument by reference or by address both enable the passed argument to be changed in the calling function by the called function.
    7Return Pointer from FunctionsC++ allows a function to return a pointer to local variable, static variable and dynamically allocated memory as well.