davidx1
davidx1

Reputation: 3673

C++ pointer gets overwritten in for loops

Could someone explain why pointers gets overwritten when variables are declared inside a loop?

For example, given the following snippet, and the user inputs 1 and 2. I would expect that the pNums array contain 2 pointers to 2 integers holding the value 1 and 2 respectively.

But instead, the console prints out 2 and 2;

#include <iostream>
using namespace std;

//Input "1 2"
int main() {
    int* pNums[2];
    for(int i = 0; i < 2; i++){
        int num;
        cin >> num;
        pNums[i] = (&num);
    }
    cout << (*pNums[0]) << endl;
    cout << (*pNums[1]) << endl; 
}

Why is this the case? And how do I get around it? What if, for example, we don't know how many numbers the user will put in, and instead of a for loop, we have a while loop? Until some conditions are met, we want to keep creating new pointers and store them into a pNums vector?

Upvotes: 1

Views: 978

Answers (3)

robthebloke
robthebloke

Reputation: 9682

for(int i = 0; i < 2; i++){
    int num; //< this is num. It lives here.
    cin >> num; 
    pNums[i] = (&num);  //< you have taken the address of num (twice!)
}
// here is when 'num' is destroyed (no longer in scope)

// so this is now pointing at something that doesn't exist. 
cout << (*pNums[0]) << endl;

Upvotes: 0

Beta
Beta

Reputation: 99094

There is only one num, and you are overwriting that. (And then causing Undefined Behavior, but never mind that.)

There are two simple ways to avoid this mistake.

1) Store objects, not pointers:

int nums[2];
for(int i = 0; i < 2; i++){
    cin >> nums[i];
}

2) Use dynamic allocation:

int* pNums[2];
for(int i = 0; i < 2; i++){
    int *p=new int;
    cin >> *p;
    pNums[i] = p;
}

Upvotes: 3

walnut
walnut

Reputation: 22152

The pointers that you are storing in pNums are to two instances of the variable num in the for block. There is one instance of the variable in each for loop iteration and these variables live only until the end of their respective iteration of the for loop body is reached.

Therefore your pointers will be invalid when the for loop exits and so trying to dereference them with e.g. *pNums[0] causes undefined behavior.

Don't store pointer, store values:

#include <iostream>
using namespace std;

//Input "1 2"
int main() {
    int pNums[2];
    for(int i = 0; i < 2; i++){
        int num;
        cin >> num;
        pNums[i] = num;
    }
    cout << pNums[0] << endl;
    cout << pNums[1] << endl; 
}

and if you need a variable number of entries in the array, use std::vector.

Upvotes: 0

Related Questions