如何在联合中使用指针

How to use pointers in an union

本文关键字:指针      更新时间:2023-10-16

我想把一维数组指针和二维数组指针放在一个联合中,这样我就可以以任何一种方式访问数据。在下面的程序中,我希望看到值9被两种方式打印出来。

#include <iostream>
class A {
public:
    union {
        int** array2D;
        int*  array1D;
    };
    A() {
        array2D = new int*[1];
        array2D[0] = new int[1];
    }
};
int main() {
    A a;
    a.array2D[0][0] = 9;
    cout << a.array2D[0][0] << endl;
    cout << a.array1D[0]    << endl;
    cout << a.array2D << endl;
    cout << a.array1D << endl;
}

实际输出:

9
146989080
0x8c2e008 //Pointer address of array2D
0x8c2e008 //Pointer address of array1D

地址是相同的,并且根据定义,多维数组以与一维数组相同的方式存储。我想知道为什么两个cout打印出不同的结果?我错过了什么?

编辑:多亏了下面的答案,我才知道我错过了什么。从array1D访问数据的修复是:

cout << *( (int*) a.array1D[0]) << endl;

首先你调用了未定义的行为

标准规定您只允许从您上次编写的union的成员中读取,因此不允许互换读取array2Darray1D(尽管它在实践中经常有效,但不推荐)。

第二;使用array1D,您试图解引用并读取当前地址(假定为,因为UB)的值已分配给new int*[1], array2D[0][0]的值位于路径的进一步步骤。


要访问您期望从a.array1D获得的值,您将需要以下内容(不推荐)

**reinterpret_cast<int**> (a.array1D);

当您使用new分配多维数组时,您这样做的方式实际上是分配了许多数组。第一个是指向array的指针数组。因此,您的a.array1D[0]实际上包含指向数组的指针,并且您正在打印指针的值。

我很确定你是否会做以下事情:

cout << (int*)a.array1D[0] << endl;

您将得到与

相同的结果:
cout << a.array2D[0] << endl;

当您打印出a.array2D的值时,它指向数组的开头。由于您使用的是联合,array1Darray2D占用相同的空间,并且包含相同的值。

当你访问a.array1D[0]中的指针值时,你告诉它获取array1D的第一个元素。因为您使用的是union,这也指向array2D的第一个元素,这恰好是一个指针。