*ptr和**ptr有什么区别?

3
我正在使用malloc和三级指针编写一个3D数组。在下面的代码中,我用*ptrdate替换了 *ptrdate in (a), *ptrdate[i], 和 *ptrdate[i],因为它们本质上都是指向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 操作数使用时,你是指它们之间的区别吗? - Kerrek SB
如果你不知道它们的含义,为什么要替换它们?回答你的问题,想一想表达式ptrdate*ptrdate*ptrdate[i]的类型。 - juanchopanza
@juanchopanza,使用 sizeof *ptrdate 时,最后一个 malloc 是错误的,对吗?第二个 malloc 也是一样的,对吗? - Spikatrix
@PumpkinCake,尝试使用“printf”中的“%zu”格式说明符打印sizeof *ptrdatesizeof *ptrdate[i]sizeof *ptrdate[i][j] - Spikatrix
4
标记为重复的问题绝对不是重复的,请投票重新开启。 - autistic
1
它们基本上都是类型为Date的指针,这是一个大胆且不正确的说法。 - n. m.
2个回答

2
我正在使用三级指针和malloc编写一个3D数组。首先,没有必要使用多个malloc调用来分配任何数组。实际上,这样做是不正确的,因为“数组”一词被认为表示单个连续内存块,即一个分配。稍后我会讲到这个问题,但首先回答你的问题:问题:作为sizeof的操作数时有何不同?答案虽然显而易见,但常常被误解。它们是不同的指针类型,在您的系统上恰好具有相同的大小和表示...但在其他系统上可能具有不同的大小和表示。重要的是要记住这种可能性,以便确保您的代码尽可能具有可移植性。给定size_t row=3, col=4, dep=5;,您可以这样声明数组:Date array[row][col][dep];。我知道您在这个问题中没有用处...稍微等一下。如果我们printf("%zu\n", sizeof array);,它将打印row * col * dep * sizeof (Date)。它知道数组的完整大小,包括所有维度...这正是分配此类数组所需的确切字节数。但如果我们像在您的代码中那样声明ptrDate,则printf("%zu\n", sizeof 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]的指针(指向Date),而sizeof *ptrDate不包含row维度(因此在上面的malloc中需要进行乘法运算)。我将把它留给您来决定是否需要解决这个问题...
free(ptrDate); // Ooops! I must remember to free the memory I have allocated!

0

int *ptr是指针的声明,它存储整数变量的地址,而int **ptr是存储指向存储整数变量的指针的地址的声明。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接