gpt4 book ai didi

c++ - 将(指向可变大小数组的指针)转换为(指向指针的指针)

转载 作者:行者123 更新时间:2023-11-30 02:45:59 25 4
gpt4 key购买 nike

当我将 [指向可变大小数组的指针] 转换为 [指向指针的指针] 时究竟发生了什么?

int ar[r][c];
int **ptr = (int**)ar; // implicit casting not allowed
ptr[0][0] = 100;

上面的代码给出了一个运行时错误。

将可变大小的数组转换为指针按预期工作:

int ar[c];
int *ptr = ar;
ptr[0] = 100;

此处 ar 衰减为指向第一个元素的指针。

但是当将 int(*)[c] 转换为 int** 时内部会发生什么?为什么在读取/写入int** 变量时会导致运行时错误?

最佳答案

数组不是指针。

数组是所有相同类型的数据的连续内存块,全部打包在一起。碰巧的是,如果您有一个指向第一个元素的指针,并且您知道数据的类型,那么您可以使用指针做很多与数组相同的事情。

foo[5] 在数组上获取第 5 个元素,在指向第一个元素的指针上也获取第 5 个元素。

事实上,您可以将数组转换为类型 foo 以隐式指向第一个元素的指针。

现在,您正在做的是完全不同的事情。指向第一个元素的指针是指向 int[5] 的指针——整个数组。

假设您有一个长度为 5 的指向 int* 的指针数组。它们中的每一个都可以指向不同的 int[5],并且您可以使用int*[6] 作为二维数组。但是您会注意到这里我们有一个指向 int* 的指针数组,而不是一个 int[5] 数组。由于数组不是指针,所以它们是不同的东西。

现在,我们可以解决这个问题。

template<unsigned...>struct indexes{typedef indexes type;};
template<unsigned Max, unsigned...Is> struct make_indexes:make_indexes<Max-1, Max-1, Is...>{};
template<unsigned...Is> struct make_indexes<0, Is...>:indexes<Is...>{};
template<unsigned Max> using make_indexes_t = typename make_indexes<Max>::type;

template<typename T, unsigned N, unsigned M, unsigned... Is>
std::array<T*, M> as_array_of_pointers( indexes<Is...>, T(&arr)[M][N] ) {
return { arr[Is]... };
};
template<typename T, unsigned N, unsigned M>
std::array<T*, M> as_array_of_pointers( T(&arr)[M][N] ) {
return as_array_of_pointers( make_indexes_t<M>{}, arr );
}

上面是一种奇特的 C++11 写法:

std::array<int*, 5> arr = { ar[0], ar[1], ar[2] };

现在你可以把你的 ar 变成一个指针数组。如果你有一个采用 int** 的函数,你可以调用 as_array_of_pointers 并采用指向第一个元素的显式指针,并依靠临时生命周期来完成工作:

void foo( int** x ) {}

int main() {
int a[5][3] = {0};
foo( &(as_array_of_pointers(a)[0]) );
}

这需要 C++11。您可以改为在 C++03 中手动执行此操作。

您看到的崩溃(通过未定义的行为)可能是将数组的第一个元素重新解释为指向 int 的指针而不是一个或多个 int< 的结果(取决于指针的相对大小和系统上的 int)。

live example

关于c++ - 将(指向可变大小数组的指针)转换为(指向指针的指针),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23997720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com