C++ Pointers – How to Manage Memory Allocations Done via malloc Inside a Loop

c++linked-listmallocpointers

I am new to C++. I am trying to implement Linked Lists and doing so using classes. In order to allocate the Nodes, I use malloc() and allocate the memory for each node inside a for loop (for the 2nd to 2nd last node).

But, when I try to print the values, by using the printList() function, the memory addresses change and I can no longer access the value stored earlier.

Code in question:

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

class Node{
    private:
        // Attributes
        int value;
        Node* nextNode;

    public:
    
        // Empty Constructor
        Node(){
            value = 0;
        }

        // Value-and-address Constructor
        Node(int localValue, Node* localAddress){
            value = localValue;
            nextNode = localAddress;
        }

        // Value Setter
        void setValue(int localValue){
            value = localValue;
        }

        // Address Setter
        void setAddress(Node* localAddress){
            nextNode = localAddress;
        }

        // Value Getter
        int getValue(){
            return value;
        }

        // Next Node Address Getter
        Node* getNextNode(){
            return nextNode;
        }
};


class linkedList{
    private:
        Node* firstNode;
        Node* lastNode;
        int sizeOfNode = sizeof(Node);
        int lengthOfList = 0;
        int iter;
        Node* container = (Node*)malloc(sizeof(Node)); // Container for last node

    public:

        // Constructor
        linkedList(int sizeOfList, int* localArray){

            // Creation of first Node
            firstNode = (Node*)malloc(sizeOfNode);
            *firstNode = Node(localArray[0], container);

            Node* previousNode = previousNode; // Current Node
            lengthOfList ++;

            for(int i = 1; i < sizeOfList-1; i++){
                iter = i;
                Node* currentNode = (Node*)malloc(sizeOfNode);
                printf("\n Next Node Location: %p", currentNode);
                (*previousNode).setAddress(currentNode);
                printf("\n Current Node Location: %p", (*previousNode).getNextNode());
                *currentNode = Node(localArray[i], container);
                previousNode = currentNode;
                lengthOfList ++;
            }

            // Creation of last Node
            iter++;            
            lastNode = (Node*)malloc(sizeOfNode);
            *lastNode = Node(localArray[iter], container);
            lengthOfList ++;
        }

        void printList(){
            // First Print
            Node* currentNode = firstNode;
            for(int i = 0; i < lengthOfList; i++){
                printf("\n%d: %d\n", i, (*currentNode).getValue());
                printf("Next Node Location: %p\n", (*currentNode).getNextNode());
                currentNode = (*currentNode).getNextNode();
            }
        }
};


int main(){

    int passedArray[] = {1, 2, 3, 4};
    int sizeOfPassedArray = sizeof(passedArray)/sizeof(int);

    linkedList list1 = linkedList(sizeOfPassedArray, passedArray);
    list1.printList();
}

Upon running it, the output is:

 Next Node Location: 00000261A1E6F940
 Current Node Location: 00000261A1E6F940
 Next Node Location: 00000261A1E6F700
 Current Node Location: 00000261A1E6F700
0: 1
Next Node Location: 00000261A1E6F780

1: 0
Next Node Location: 0000000000000000

The reason I think the address is changed when the loop is exited is because:

  1. The output prints a different address.

  2. I can still access the firstNode normally.

What is the issue, and how do I solve it?

The debugger shows segmentation fault at the return value line in the getValue() function, if that is relevant, but that is only from the second iteration of the printList() loop and onwards.

Best Answer

I will try to summarize it for you:

  1. malloc will never call the constructor of your class as it is mainly used for C not for C++.
  2. to dynamically allocate class instances in C++ you should use new instead of malloc
  3. allocated memory using malloc or new must be freed with free or delete respectively
  4. using free will never call your instance destructor

once you are done with your instance delete it.

Related Question