首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >int**类型和int[][]类型有什么区别?

int**类型和int[][]类型有什么区别?
EN

Stack Overflow用户
提问于 2011-12-06 12:12:23
回答 1查看 2.2K关注 0票数 19

如果以下分配有效:

代码语言:javascript
运行
复制
int a[2] = {1,2};
int* b = a;

那么这样做有什么问题:

代码语言:javascript
运行
复制
int a[2][2]={1,2,3,4};
int** b = a;

C++给出了一个错误,它无法将int[][]转换为int**。如果int[]int*相同,那么这两种类型之间有什么区别

EN

回答 1

Stack Overflow用户

发布于 2011-12-06 12:40:36

这是经常出现的事情,所以我将尽可能清楚地解释它。

当您创建数组时,它将元素连续地存储在内存中,因此:

代码语言:javascript
运行
复制
int arr[2] = { 1, 2 };

翻译为:

代码语言:javascript
运行
复制
arr:
+---+---+
| 1 | 2 |
+---+---+

指针指向内存中的一个对象,当被解除引用时,它通过一元*[]访问那个连续的内存。所以在

代码语言:javascript
运行
复制
int *ptr = arr;

ptr (如果您喜欢,也可以称为&ptr[0] )指向1所在的框,而ptr + 1 (或&ptr[1])指向2所在的框。这是有道理的。

但是如果数组在内存中是连续的,那么数组的数组在内存中也是连续的。所以:

代码语言:javascript
运行
复制
int arr[2][2] = {{ 1, 2 }, { 3, 4 }};

内存中的内容如下所示:

代码语言:javascript
运行
复制
arr:
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+

它看起来很像我们的平面阵列。

现在,让我们考虑一下指向int的指针在内存中是如何布局的:

代码语言:javascript
运行
复制
ptr:
+-------+-------+
| &sub1 | &sub2 |
+-------+-------+

sub1:
+---+---+
| 1 | 2 |
+---+---+

sub2:
+---+---+
| 3 | 4 |
+---+---+

ptr (或&ptr[0])指向sub1ptr + 1 (或&ptr[1])指向sub2sub1sub2彼此没有实际关系,可以在内存中的任何位置,但因为它是指向指针的指针,所以保留了2D数组的双重引用,即使内存结构不兼容。

类型为T的数组衰减为指向类型T的指针,但类型为T的数组不衰减为指向类型T的指针,它们衰减为指向类型为T的数组的指针。因此,当我们的2D arr衰减为指针时,它不是指向int的指针,而是指向int [2]的指针。这种类型的全名是int (*)[2],要使您的代码行正常工作,您需要使用

代码语言:javascript
运行
复制
int (*ptr)[2] = arr;

哪一个是正确的类型。ptr希望指向一个连续的内存数组,就像arr一样-- ptr (或&ptr[0])指向arrptr + 1 (或&ptr[1])指向&arr[1]ptr[0]指向容纳1的盒子,ptr[1]指向容纳3的盒子,因此ptr[0][0]产生1,ptr[0][1]产生2,依此类推。

为什么你需要知道这一点? 2D指针似乎比它们的价值更复杂-如果你使用malloc,你必须在循环中重复调用malloc,并对free做同样的事情。或者,您可以使用一些邪恶的*技巧来使一个平面的一维内存分配行为类似于一个2D数组:

代码语言:javascript
运行
复制
// x and y are the first and second dimensions of your array
// so it would be declared T arr[x][y] if x and y were static

int (*arr)[y] = malloc(x * y * sizeof(arr[0][0]));
if(!arr) /* error */;

现在,arr指向大小为yint对象数组的连续块。因为它指向的对象是一个数组,所以我们不需要int **对象的双指针间接寻址,当您完成后,您可以通过一次调用释放它:

代码语言:javascript
运行
复制
free(arr);

将其与使用int **的版本进行比较

代码语言:javascript
运行
复制
int **arr = malloc(x * sizeof(*arr));
if(!arr) /* error */;
for(size_t ii = 0; ii < x; ii++)
  {
    arr[ii] = malloc(y * sizeof(**arr));
    if(!arr[ii])
      {
        free(arr[ii]);
        free(arr);
      }
  }
// do work
for(size_t ii = 0; ii < x; ii++)
    free(arr[ii]);
free(arr);

上面的代码有一个内存泄漏。看看你能不能找到。(或者只使用带有那些看似棘手的数组指针的版本。)

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8395255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档