Memelord Supreme
Memelord Supreme

Reputation: 31

C++ pointer/for-loop confusion

I'm trying to write a program that reads values from cin using a pointer, and then outputs the values alongside their position in the array. I can't figure out why printNumbers1 works but printNumbers2 doesn't. Here is the program (relevant code near the bottom):

#include <iostream>

using namespace std;

int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);

int main()
{
    int *numbers = readNumbers(5);
    printNumbers1(numbers);
    printNumbers2(numbers);
    return 0;
}

int *readNumbers(int n)
{
    int a[n];
    int *numbers;
    numbers = &a[0];
    for (int i=0; i<n; i++)
    {
        cin >> *(numbers+i);
    }

    return numbers;
}

void printNumbers1(int *numbers)
{
    cout << 0 << ' ' << *(numbers) << endl
         << 1 << ' ' << *(numbers+1) << endl
         << 2 << ' ' << *(numbers+2) << endl
         << 3 << ' ' << *(numbers+3) << endl
         << 4 << ' ' << *(numbers+4) << endl;
}

void printNumbers2(int *numbers)
{
    for (int i=0; i<5; i++)
    {
        cout << i << ' ' << *(numbers+i) << endl;
    }
}

When I run the program, it works as intended for printNumbers1 but outputs a combination of seemingly random numbers and 0s for printNumbers2. I feel like the two printNumbers functions should should function identically, but they don't. What am I missing?

Upvotes: 2

Views: 3600

Answers (3)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727077

This happens because of a combination of two things:

  • C++ does not allow variable-length arrays - this is a popular extension, but the declaration int a[n] is not standard.
  • You cannot return a pointer to local variable from a function - pointer numbers inside readNumbers points to a, a local variable. You can use this pointer inside the function, but outside of the function it becomes invalid, because a goes out of scope.

Using an out-of-scope variable causes undefined behavior. This Q&A provides a very good explanation of what is happening, and why it may look like the program is working fine.

If you want to use built-in pointers, remove int a[n], and change the declaration of numbers as follows:

int *numbers = new int[n];

You also need to add

delete[] numbers;

before return 0 line to avoid memory leaks.

I am assuming that you wrote this code as part of a learning exercise. In general, though, a better approach in C++ is to use std::vector<int>, which hides pointer operations from your code, and deals with resource management for you.

Upvotes: 3

Arvindsinc2
Arvindsinc2

Reputation: 714

Here you have created the array a[n] inside the function, so it is a local variable, Hence this array may or may not be deleted after the scope of the function ends.Never use the address of a local variable outside the funcrtion. This code is working:

#include <iostream>

using namespace std;

int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);

int main()
{
    int *numbers = readNumbers(5);
    printNumbers1(numbers);
    printNumbers2(numbers);
    return 0;
}

int *numbers;

int *readNumbers(int n)
{

    numbers = new int[n];
    for (int i=0; i<n; i++)
    {
         cin >> *(numbers+i);
    }

    return numbers;
}

void printNumbers1(int *numbers)
{ 
cout << 0 << ' ' << *(numbers) << endl
     << 1 << ' ' << *(numbers+1) << endl
     << 2 << ' ' << *(numbers+2) << endl
     << 3 << ' ' << *(numbers+3) << endl
     << 4 << ' ' << *(numbers+4) << endl;
}

void printNumbers2(int *numbers)
{
for (int i=0; i<5; i++)
{
    cout << i << ' ' << *(numbers+i) << endl;
}
}

Upvotes: 0

Bathsheba
Bathsheba

Reputation: 234875

readNumbers returns a pointer to a variable with automatic storage duration.

The behaviour on dereferencing that pointer is undefined.

Use a std::vector instead. Rely on return value optimisation to obviate any superfluous value copies being taken.

Upvotes: 1

Related Questions