3

I'm super duper new to coding and I'm just learning this as a hobby. I'm following a course and this is the code I wrote (user input to a dynamically created array):

#include <iostream>

using namespace std;

int main()
{
    int capacity = 5;
    int* numbers = new int[capacity];
    int index=0;

    while (true)
    {       
        cout << "Please enter a whole number. ";
        cin >> numbers[index];
        if (cin.fail())
        {
            cout << "That's not a whole number, ya dingus. Here's all yer numbers so far:" << endl;
            break;
        }
        index++;
        if (index == capacity)
        {
            int* morenumbers = new int[2*capacity];
            for (int j = 0; j < index;j++)
            {
                morenumbers[j] = numbers[j];
            }
            delete[] numbers;
            numbers = morenumbers;
        }
    }

    for (int i = 0; i < index;i++)
        cout << numbers[i] << endl;
    delete[] numbers;

    return 0;
}

My questions are:

  1. I set the initial size of the array to 5 and it can be increased to 10. Why the heck does it work for 20 numbers as well?

  2. The variable index that I declared changes in the while loop. So, if I'm not wrong, its scope is within the while loop, right? Then, why is it that I can use it outside of the while loop (as for example my last for loop that prints out all the entered numbers)?

My main focus right now is not writing efficient code, but learning what the commands do, so despite the code apparently working flawlessly, I want to know why it works.

14
  • This question currently includes multiple questions in one. It should focus on one problem only. Commented May 16 at 1:06
  • Possible duplicate of the first question: Undefined, unspecified and implementation-defined behavior Commented May 16 at 1:07
  • 1
    (1) Undefined behavior is undefined. "Seems to work" is one possible manifestation of undefined behavior. (2) No, you don't magically shrink the scope of a variable by assigning to it. The scope is determined by where a name is declared, not by how it's used. Commented May 16 at 1:15
  • 4
    I'm super duper new to coding -- If that's the case, what course are you taking that advocates the usage of new[] so early on in your C++ coding endeavors? A modern C++ course would be teaching uses of std::vector, as new[] is not a beginner topic, and frankly, shouldn't be used if the goal is to have a dynamic array. Commented May 16 at 1:41
  • 1
    @EllonFeyneth Using std::vector and an alternate using at() makes it clearer as to the logic and the mistake that's being made. Using new[], you have no guarantees as to what happens when you stomp on memory that you didn't allocate. My main focus right now is not writing efficient code -- it isn't about efficient code -- it's about writing code that is easier to debug, easier to follow and easier to maintain. Commented May 16 at 1:51

1 Answer 1

9

I set the initial size of the array to 5 and it can be increased to 10. Why the heck does it work for 20 numbers as well?

It doesn't "work", actually. You have a logic bug in your code, which causes Undefined Behavior after 10 numbers have been entered.

When you re-allocate the array, you are not updating the capacity variable to reflect the new size. So, you will end up re-allocating the array only 1 time total, after the 5th number is entered. After the 10th number is entered, you will start trashing memory when you save subsequent numbers into array slots that you did not allocate memory for.

You need to update the capacity variable when you update the numbers variable, eg:

numbers = morenumbers;
capacity *= 2; // <-- add this!

That being said, if you want to learn C++ properly, then modern practice is to NOT directly use new[]/delete[] at all. Consider them only for advanced use cases, not for beginner use cases. In this example, you can instead use std::vector, which is C++'s standard dynamic array type. Let it handle the memory management for you, eg:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> numbers(5);
    int number, index = 0;

    while (true)
    {       
        cout << "Please enter a whole number. ";

        if (!(cin >> number))
        {
            cout << "That's not a whole number, ya dingus." << endl;
            break;
        }

        if (index == numbers.size())
            numbers.resize(2*index);

        numbers[index] = number;
        ++index;
    }

    cout << "Here's all yer numbers so far:" << endl;

    for (int i = 0; i < index; ++i)
        cout << numbers[i] << endl;

    return 0;
}

Which can be simplified by getting rid of index altogether:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> numbers;

    while (true)
    {       
        cout << "Please enter a whole number. ";

        int number;
        if (!(cin >> number))
        {
            cout << "That's not a whole number, ya dingus." << endl;
            break;
        }

        numbers.push_back(number);
    }

    cout << "Here's all yer numbers so far:" << endl;

    for (int number : numbers)
        cout << number << endl;

    return 0;
}

The variable index that I declared changes in the while loop. So, if I'm not wrong, its scope is within the while loop, right?

You declared index in the outermost {} block of main(), so its lifetime ends at the end of main(), and its scope includes both loops but is not limited to either loop.

Then, why is it that I can use it outside of the while loop (as for example my last for loop that prints out all the entered numbers)?

Because index is still in scope when the for loop is reached. See Scope on cppreference.com for more details.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.