I tried to create an array that would increase its own size depending on the user's action.

For example:

The user types the name of one contestant, the array contains only one element (the name), later the user enters another contestant, the array becomes an array of 2 elements, each element with the corresponding name, etc...

The problem is that for some mysterious reason the program crashes at contestant number 10, I have tried to use delete [] name_address, every time the loop iterate, but it just made the program crash at contestant number 6.

If anyone has an explanation, please do so.

Code:

int array_subscript;
    double averages_final[3];
    double score[5];
    char input[40];
    int number_of_contestants = 0;
    string name;
    string *name_address;
    
    while (true)
    {
        cout << "Contestant " << number_of_contestants + 1 << " name? (Enter '!' when finished) ";
        getline(cin, name);
        
        if (name == "!")
            break;
        
        number_of_contestants++;

        name_address = new string[number_of_contestants];
        static string *pointer = 0;
        
        for (int i = 0 ; i < number_of_contestants - 1 ; i++)
            name_address[i] = pointer[i];
   
        name_address[number_of_contestants-1] = name;
        string names[number_of_contestants];
        
        for (int i = 0 ; i < number_of_contestants ; i++)
            names[i] = name_address[i];
            
        pointer = names;
    }

Ouch, your logic is bad. You are killing your program slowly. Luckily it
fights back with the runtime exceptions.

Can you comment line by line so I see what your thinking process is.
That way you will learn better when you see whats wrong.

Agree. Just a comment... It seems every iteration: name_address and names are created again. I don't think this is the behavior you would like.

Edited 7 Years Ago by jasonline: n/a

Your code is not safe. Even though you're using a pointer to point to names[], this space is released each iteration since names[] is a local variable declared inside the loop. This space may be allocated to others and using the pointer variable to access it may corrupt the memory. Also, don't forget to use delete[] to avoid memory leak.

Thanks for replying, I indeed wanted the names array and name_address to be recreated each iteration. This is because I thought that it would be the only way to make an array with a size of exactly the number of contestants.

int array_subscript; // This variable will be used in other part of the code
    double averages_final[3]; // The same
    double score[5]; // Same
    char input[40]; // Same
    int number_of_contestants = 0; // Variable that will hold the number of contestants, will increase each "iteration, with the exception of the last one (user presses '!').
    string name; // Will hold the name and the pass it to the array.
    string *name_address; // Will allocate memory each iteration depending on the number of contestants.
 
    while (true)
    {
        cout << "Contestant " << number_of_contestants + 1 << " name? (Enter '!' when finished) ";
        getline(cin, name); // Gets name
 
        if (name == "!") // If name is !, it means the user wanted to exit the loop.
            break;
 
        number_of_contestants++; // If not, add one to number_of_contestants.
 
        name_address = new string[number_of_contestants]; // Allocate an array in memory that will have exactly the size of the number_of_contestants, this is why I recreate it, every iteration.
        static string *pointer = 0; // Define a pointer, later it will point to names.
 
        for (int i = 0 ; i < number_of_contestants - 1 ; i++)
            name_address[i] = pointer[i]; // This will be executed every iteration, after the first iteration, this is what passes the values of names to name_address.
 
        name_address[number_of_contestants-1] = name; // Recieve the name that the user entered, for example first name (first iteration) received with name_address[0], then second name in name_address[1], and so on.
        string names[number_of_contestants]; // This array is needed to hold the values that will be erased from name_address every iteration, it will also need a "dynamic" size to be able to hold them.
 
        for (int i = 0 ; i < number_of_contestants ; i++)
            names[i] = name_address[i]; // Before beginning a new iteration, the values of name_address will be passed to names.
 
        pointer = names; // Points to names, I did this because I needed to "use" names before it even existed, so the only way I could do it was with a pointer.

// With even existed I mean that I need to pass the values that names hold to name_address, but to do that I would need to call it before "recreating it (second to last iteration), or creating it (first iteration)", so I realized that I could use a pointer.
    }

To jasonline:

Thank you for your response, but I used the delete command before, exactly in the last part of the iteration ( delete [] name_address; ), what happened was an earlier crash (6 iteration instead of 10), and about the pointer to names, I saw that names[] holds its address until it is recreated, so I thought that I could use a pointer, manipulate the information in names[], and then recreate it and repeat the process.

Edited 7 Years Ago by Kuroshi: n/a

I see then. How about just doing this inside your loop:

inside your loop
{
...

declare temporary static array
copy dynamic array contents (if not empty) into static array
resize dynamic array (delete[], then allocate current size + 1)
copy static array contents (if not empty) into dynamic array
insert new item into dynamic array at the end

}

You don't need to use that pointer in your old code because that was unsafe, pointing to a memory that gets destroyed every end of the iteration.

There are other better ways to do this (e.g use list data structure implemented using an array) but we'll just stick to your code.

Edited 7 Years Ago by jasonline: additional info

I see then. How about just doing this inside your loop:

inside your loop
{
...

declare temporary static array
copy dynamic array contents (if not empty) into static array
resize dynamic array (delete[], then allocate current size + 1)
copy static array contents (if not empty) into dynamic array
insert new item into dynamic array at the end

}

You don't need to use that pointer in your old code because that was unsafe, pointing to a memory that gets destroyed every end of the iteration.

There are other better ways to do this (e.g use list data structure implemented using an array) but we'll just stick to your code.

Thank you very much, I finally made it work :D. I forgot that I could use the pointer that I created outside the loop (at the beginning), instead of that risky pointer at the end :P.

And I will check for other ways of doing this, as you said. Thank you very much for the help.

Edited 7 Years Ago by Kuroshi: n/a

This question has already been answered. Start a new discussion instead.