为什么不同的指针就像他们共享相同的价值观一样?

时间:2014-12-31 03:21:30

标签: c++ arrays pointers

下面我使用了两个不同的函数来初始化2D数组。每个返回一个数组,该数组存储在适当的指针中。没有全局变量。当一个人获得一个价值时,他们都表现得好像已经收到了。代码和日志说明。

尽我所能,我不明白为什么这是有道理的。首先,两个未初始化的值都是有意义的。但之后为什么设置A也设置B相同?为什么然后设置B覆盖A?

代码:

#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;
}

日志:

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

3 个答案:

答案 0 :(得分:5)

MakePtrArrayB通过使用未初始化的指针调用未定义的行为。

未定义的行为可以是任何,但在您的情况下,myArr中的MakePtrArrayB指针可能占用与MakePtrArrayA中的{{1}}指针相同的内存,因此循环访问原始数组(将其设置为新分配的行缓冲区,对于后续访问来说足够大。)

但你不能依赖这种行为。修复错误。

答案 1 :(得分:3)

您没有初始化myArrMakePtrArrayB的值。因此,取消引用该指针的结果是未定义 - 任何可能发生的事情。

在这种情况下,正在发生的事情是myArr的值正在重复使用前一次调用MakePtrArrayA期间设置的相同值。 (这很可能发生,因为这两个函数具有相同的堆栈布局,并且堆栈位置没有被其他任何东西覆盖。)显然,你不应该依赖于这种行为!它不会可靠地运作。

答案 2 :(得分:0)

以前的答案中没有提到的另一个问题是您在arrA上访问越界:

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

主要:

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