How to correctly read inputs into a dynamically allocated array of objects

I am currently working on a project which is a ticket storage system that stores each ticket holder as an object.

To input the values, I am using a parameterized constructor. In the main function I have declared a dynamic memory block for an array of these objects.

The main issue I face is that in the for loop that initializes each object, the loop only runs once, then terminates. Here is the code:

#include <iostream>
#include <stdlib.h>
#include <string>

using namespace std;
class node
{
    string holder_name;
    int age;

public:
    node(string a, int b)
    {
        holder_name = a;
        age = b;
    }

    void view()
    {
        cout << "Name: " << holder_name << endl;
        cout << "Age: " << age << endl;
    }
};
int main()
{
    int count, i;
    cout << "Enter no of nodes" << endl;
    cin >> count;
    node *arr = (node *)malloc(sizeof(node) * count);

    for (i = 0; i < count; i++)
    {
        int b;
        string str;
        cout << "Enter name" << endl;
        cin >> str;
        cout << "Enter age" << endl;
        cin >> b;
        arr[i] = node(str, b);
        arr[i].view();
    }
    return 0;
}

Answer

That is a fine example why malloc is not used in C++, when you allocate memory for your nodes, the elements are not initialized.

Allocation in C++ is done with new wich guards against the aforementioned problem:

node *arr= new node[count];

In this case you’ll also need to add a default constructor to your class

node() = default; or node(){};

A better solution, however, is to use one of the resizable containers provided by C++ containers library, for instance std::vector:

#include <vector>
int main()
{
    int count, i;
    cout << "Enter no of nodes" << endl;
    cin >> count;
    std::vector<node> arr; // now you have a resizable container
    for (i = 0; i < count; i++)
    {
        int b;
        string str;
        cout << "Enter name" << endl;
        cin >> str;
        cout << "Enter age" << endl;
        cin >> b;
        arr.push_back(node(str, b)); // keep adding elements
        arr[i].view();
    }
}

Here you could also create the vector with an initial size as suggested in S.M. answer, it really deppends on the sizes you expect for your container, if it’s on the larger side it’s better because it avoids memory reallocation, in which case the insersion would be exactly as you have it in your original code.

Footnote

I should add that using namespace std; is not the most recommended techinque, you can find the reasoning and alternative methods here:

Why is “using namespace std;” considered bad practice?

Leave a Reply

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