下面我使用了两个不同的函数来初始化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
答案 0 :(得分:5)
MakePtrArrayB
通过使用未初始化的指针调用未定义的行为。
未定义的行为可以是任何,但在您的情况下,myArr
中的MakePtrArrayB
指针可能占用与MakePtrArrayA
中的{{1}}指针相同的内存,因此循环访问原始数组(将其设置为新分配的行缓冲区,对于后续访问来说足够大。)
但你不能依赖这种行为。修复错误。
答案 1 :(得分:3)
您没有初始化myArr
中MakePtrArrayB
的值。因此,取消引用该指针的结果是未定义 - 任何可能发生的事情。
在这种情况下,正在发生的事情是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