【问题标题】:What are the differences between *ptr and **ptr?*ptr 和 **ptr 有什么区别?
【发布时间】:2015-04-25 07:35:22
【问题描述】:

我正在使用带有 malloc 的三重指针编写一个 3D 数组。我在下面的代码中将*ptrdate in (a)*ptrdate[i]*ptrdate[i] 替换为*ptrdate,因为它们基本上都是Date 类型的指针,但访问维度不同。两种方式我得到了相同的结果。

问:作为sizeof的操作数有什么区别?

typedef struct {
    int day;
} Date;

int main(){
  int i, j, k, count=0;
  int row=3, col=4, dep=5;

  Date ***ptrdate = malloc(row * sizeof *ptrdate); //(a)
  for (i=0; i<row; i++) {
    ptrdate[i] = malloc(col * sizeof *ptrdate[i]); //(b)
    for (j=0; j<col; j++) {
      ptrdate[i][j] = malloc(dep * sizeof *ptrdate[i][j]); //(c)
    }
  }

【问题讨论】:

  • 你的意思是作为sizeof的操作数有什么区别?
  • 如果您不知道它们的含义,为什么要替换它们?要回答您的问题,请考虑表达式 ptrdate*ptrdate*ptrdate[i] 的类型。
  • @juanchopanza , 最后一个 malloc 在使用 sizeof *ptrdate 时会出错,对吧?第二个malloc 也是如此,对吧?
  • 标记为重复的问题肯定不是重复的。请投票重新开放。
  • "它们基本上都是 Date 类型的指针"。这是一个大胆且不正确的说法。

标签: c pointers memory malloc


【解决方案1】:

我正在使用带有malloc 的三重指针编写一个 3D 数组。

首先,没有必要通过多次调用malloc 来分配任何数组。事实上,这样做是不正确的,因为“数组”一词被认为表示单个连续内存块,即 one 分配。我稍后会谈到,但首先,你的问题:

问题:作为sizeof的操作数有什么区别?

答案虽然显而易见,但经常被误解。它们是不同的指针类型,巧合的是,它们在您的系统上具有相同的大小和表示形式……但它们在其他系统上可能具有不同的大小和表示形式。记住这种可能性很重要,这样您就可以确保您的代码尽可能可移植。

给定size_t row=3, col=4, dep=5;,您可以像这样声明一个数组:Date array[row][col][dep];。我知道你在这个问题上没有用这样的声明......请容忍我一会儿。如果我们printf("%zu\n", sizeof array);,它将打印row * col * dep * sizeof (Date)。它知道数组的完整大小,包括所有维度……这确切地是分配这样一个数组时需要多少字节。

printf("%zu\n", sizeof ptrDate);ptrDate 在你的代码中声明会产生完全不同的东西,但是......它会产生一个指针的大小(指向指向 Date 的指针的指针,不要与 指向Date的指针或指向Date的指针)。所有关于维度数量的大小信息(例如row * col * dep 乘法)都丢失了,因为我们没有告诉指针维护该大小信息。不过,我们仍然可以使用sizeof *ptrDate 找到sizeof (Date),因为我们已经告诉我们的代码保持与指针类型相关联的大小信息。

如果我们可以告诉我们的指针来维护其他大小信息(尺寸)呢?如果我们可以写ptrDate = malloc(row * sizeof *ptrDate);,并且让sizeof *ptrDate 等于col * dep * sizeof (Date),会怎样?这会简化分配,不是吗?

这让我们回到我的介绍:有一种方法可以使用单个 malloc 来执行所有这些分配。这是一个简单易记的模式,但很难理解(可能适合问另一个问题):

Date (*ptrDate)[col][dep] = malloc(row * sizeof *ptrDate);

可以这么说,用法仍然基本相同。您仍然可以像 ptrDate[x][y][z] 一样使用它...不过,有一件事似乎不太正确,那就是 sizeof ptrDate 仍然会产生指针的大小(指向 @ 的数组 [col] [dep] 987654343@) 和sizeof *ptrDate 不包含row 维度(因此在上面malloc 中的乘法。我将把它作为练习留给您,以确定是否需要解决方案......

free(ptrDate); // Ooops! I must remember to free the memory I have allocated!

【讨论】:

    【解决方案2】:

    int *ptr 是指针的声明,存放整型变量的地址,int **ptr 是存放整型变量的指针地址的声明。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-11
      • 2013-01-16
      • 1970-01-01
      • 2022-01-15
      • 2021-02-28
      • 1970-01-01
      相关资源
      最近更新 更多