3

我正在回答这个问题,但是当我测试以下代码时,我感到困惑。

#include <iostream>

using namespace std;

int main()
{
        int **ptr;
        int arr[3][3];
        ptr =(int **) arr;
        for (int i=0;i<3;i++){
                for (int j=0;j<3;j++){
                        cout << &arr[i][j] << " =? ";
                        cout << &(ptr[i][j]) << endl;
                }

        }


        return 0;
}

但我得到这个输出:

0x7fff5700279c =? 0
0x7fff570027a0 =? 0x4
0x7fff570027a4 =? 0x8
0x7fff570027a8 =? 0
0x7fff570027ac =? 0x4
0x7fff570027b0 =? 0x8
0x7fff570027b4 =? 0
0x7fff570027b8 =? 0x4
0x7fff570027bc =? 0x8

为什么他们不一样?

4

3 回答 3

12
ptr =(int **) arr;

这非常糟糕 - 它涉及 areinterpret_cast并导致未定义的行为。这两种类型 - anint[3][3]和 an int**- 在内存布局方面完全不兼容。

3×3 2D 数组是一个连续的内存块,如下所示:

  0,0   0,1   0,2   1,0   1,1   1,2   2,0   2,1   2,2
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ int │ int │ int │ int │ int │ int │ int │ int │ int │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘

指向int每个指针指向数组中第一个元素的指针的指针如下所示:

┌─────┐
│     │ // The int**
└──╂──┘
   ┃
   ▼
┌─────┬─────┬┄
│     │     │   // An array of int*
└──╂──┴──╂──┴┄
   ┃     ┗━━━━━━━━━━┓
   ▼                ▼
┌─────┬─────┬┄   ┌─────┬─────┬┄
│ int │ int │    │ int │ int │    // Arrays of ints
└─────┴─────┴┄   └─────┴─────┴┄
  0,0   0,1        1,0   1,1

这涉及两个间接级别。二维数组类型没有要通过的指针数组。此外,int在这种int**情况下,s 的数组不一定是连续的。

So think about when you do ptr[0], for example. What is the type of the expression? Since ptr is an int**, the type of ptr[0] is an int*. However, what is actually at the location ptr[0]? Not a pointer at all! Instead, there's an array of ints.

于 2013-03-23T13:49:31.207 回答
10

int **ptr和 anint arr[3][3]不同,因为:

 -----------------------------------
|    C    |         Maths           |
 -----------------------------------
| ptr + 1 | ptr + sizeof(int*)      |
 -----------------------------------
| arr + 1 | arr + 3 * sizeof(int*)  |
 -----------------------------------

所以你根本不会得到相同的结果(此外,ptr可能arr没有相同的内存表示)。

int (*ptr)[3] = arr;

会起作用,因为只有第一个维度arr会衰减为指针。

于 2013-03-23T13:46:25.523 回答
1

int** 是一个指向 int 的指针。这意味着它指的是一个指针数组。但是, int[x][y] 是大小为 x x y 的整数数组。它是一个单独的内存块,排列成 x 行,每列 y 列(如果你愿意这样想的话。

要实现您想要的,您必须收集列的地址并将它们存储在 int** 指针的行中。

int   arry[3][3];
int** ptr = malloc( sizeof(int*) * 3 );

for( int i = 0; i < 3; i++ )
   ptr[i] = arry[i];

for( int i = 0; i < 3; i++ )
    for( int j = 0; j < 3; j++ )
        printf( "%d -> %d\n", arry[i][j], ptr[i][j];

free( ptr );
于 2013-03-23T13:48:05.617 回答