Question

I'm programming doubly linked list, everything was going fine but I faced with crash when reading a string value to the structure (code row is commented in the function "struct Node* GetNewNode()"):

        #include <iostream>
        #include <String>
        #include <fstream>
        #include <cstdlib>

        using namespace std;

        struct Node {
            int sv;
            double real;
            bool log;
            char simb;
            string str;
            struct Node* next;
            struct Node* prev;
        };

        struct Node* head; // global variable - pointer to head node.
        //----------------------------
        struct Node* GetNewNode();
        void Initialize(Node *stack);
        void InsertAtTail(Node *stack);
        void Print(Node *stack);
        //----------------------------
        //Creates a new Node and returns pointer to it.

        ifstream fd("duom.txt");
        struct Node* GetNewNode() {
            struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
            fd >> newNode->sv;
            fd >> newNode->real;
            string loginis;
            fd >> loginis;
            if (loginis == "TRUE")
                newNode->log = true;
            else
                newNode->log = false;
            fd >> newNode->simb;
            //fd >> newNode->str;           //uncommented code in this row crashes the program
            newNode->prev = NULL;
            newNode->next = NULL;
            return newNode;
        }

        //Inserts a Node at head of doubly linked list
        void Initialize(Node *stack) {
            stack = head;
        }

        //Inserts a Node at tail of Doubly linked list
        void InsertAtTail(Node *stack) {
            struct Node* temp = stack;
            struct Node* newNode = GetNewNode();
            if(head == NULL) {
                head = newNode;
                return;
            }
            while(temp->next != NULL)
                temp = temp->next; // Go To last Node
            temp->next = newNode;
            newNode->prev = temp;
        }

        //Prints all elements in linked list in reverse traversal order.
        void Print(Node *stack) {
            struct Node* temp = stack;
            if(temp == NULL)
                return; // empty list, exit
            // Going to last Node
            while(temp->next != NULL)
                temp = temp->next;
            // Traversing backward using prev pointer
            while(temp != NULL) {
                cout << temp->sv << " ";
                cout << temp->real << " ";
                if (temp->log == true)
                    cout << "TRUE " << " ";
                else
                    cout << "FALSE " << " ";
                cout << temp->simb << " ";
                //cout << temp->str << "\n";
                temp = temp->prev;
            }
            printf("\n");
        }

        int main() {

            /*Driver code to test the implementation*/
            head = NULL; // empty list. set head as NULL.
            // Calling an Insert and printing list both in forward as well as reverse direction.
            Initialize(head);
            InsertAtTail(head);
            Print(head);
            InsertAtTail(head);
            Print(head);
            fd.close();
        }

Input data is:
4 5.27 TRUE $ asdf
6 7.3 TRUE # qwer
9 8.8 FALSE @ zxvc
7 6.35 FALSE ! vbmn
1 0.89 TRUE % ghjk

Can somebody explain what is wrong here?

Was it helpful?

Solution

Instead of using C standard function malloc

      struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

you have to use operator new

In this case the compiler will call a constructor of class std::string that to create data member str Othewise object str of type std::string will not be created and the program will chash.

Function malloc simply allocates a raw memory of a requested size. It knows nothing about constructors of classes.

OTHER TIPS

malloc allocates a raw block of memory. This is sufficient for simple (POD) datatypes which only store data. A std::string however needs to have its constructor called to be initialized correctly. Therefore you must allocate the node using new:

Node* newNode = new Node();

In general, malloc is very rarely needed in C++ (it doesn't call any constructors). It is a C-function.

Note that you need to call delete instead of free to free memory allocated by new.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top