A Questioner
A Questioner

Reputation: 65

Why Would Different Pointers Act As If They Shared The Same Values?

Below I used two different functions to initialize a 2D array. Each returns an array, which is stored in an appropriate pointer. There are no global variables. When one is given a value, they both act as if they have received it. Code and log illustrate.

Try as I might, I can't see why this makes sense. At first, both uninitialized values makes sense. But after that why does setting A also set B the same? Why does then setting B overwrite A?

Code:

#include <iostream>

int **MakePtrArrayA( int Size ){
    int ** myArr = new int*[ Size ];
    for( int x=0; x<Size; x++ ){
        myArr[x] = new int;
    }
    return myArr;
}

int **MakePtrArrayB( int Size){
    int ** myArr;
    for( int x=0; x<Size; x++ ){
        myArr[x] = new int[ Size ];
    }
    return myArr;
}

int main(){
    int ** arrA = MakePtrArrayA( 5 );
    int ** arrB = MakePtrArrayB( 5 );
    std::cout << "A:" << arrA[4][4] << std::endl << "B:" << arrB[4][4] << std::endl;
    arrA[4][4] = 16;
    std::cout << "A:" << arrA[4][4] << std::endl << "B:" << arrB[4][4] << std::endl;
    arrB[4][4] = 15;
    std::cout << "A:" << arrA[4][4] << std::endl << "B:" << arrB[4][4] << std::endl;

    return 0;
}

Log:

A:0
B:0
A:16
B:16
A:15
B:15

Upvotes: 2

Views: 89

Answers (3)

M.M
M.M

Reputation: 141586

Another problem not mentioned by previous answers is that you access out of bounds on arrA:

int **MakePtrArrayA( int Size ){
    int ** myArr = new int*[ Size ];
    for( int x=0; x<Size; x++ ){
        myArr[x] = new int;             // <--- row length 1

In main:

std::cout << "A:" << arrA[4][4]         // <--- access 5th element

Upvotes: 0

user149341
user149341

Reputation:

You are not initializing the value of myArr in MakePtrArrayB. As such, the result of dereferencing that pointer is undefined — anything could potentially happen.

In this case, what's happening is that the value of myArr is reusing the same value that was set during the previous call of MakePtrArrayA. (This is most likely happening because the two functions have the same stack layout, and the stack location has not been overwritten by anything else.) Obviously, you should not depend on this behavior! It won't work reliably.

Upvotes: 3

Ben Voigt
Ben Voigt

Reputation: 283664

MakePtrArrayB invokes undefined behavior, by using an uninitialized pointer.

Undefined behavior can be anything, but in your case, the myArr pointer in MakePtrArrayB probably occupies the same memory as the one in MakePtrArrayA, so the loop accesses the original array (setting it to newly allocated row buffers that are big enough for the subsequent accesses).

But you cannot rely on this behavior. Fix the bugs.

Upvotes: 5

Related Questions