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

时间:2015-04-25 07:35:23

标签: c pointers memory malloc

我使用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)
    }
  }

2 个答案:

答案 0 :(得分: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)。它知道数组的完整大小,包括所有维度......这是完全分配这样一个数组时需要多少字节。

在代码中声明为printf("%zu\n", sizeof ptrDate);

ptrDate会产生完全不同的东西,但是......它会产生指针的大小(指向指向Date的指针,不要与系统上指向Date指针或指向Date 的指针的指针混淆。关于维度数量(例如row * col * dep乘法)的所有大小信息都丢失了,因为我们没有告诉我们指针维护该大小信息。不过,我们仍然可以使用sizeof (Date)找到sizeof *ptrDate,因为我们告诉我们的代码保留与指针类型相关联的大小信息。

如果我们可以告诉我们的指针来维护其他尺寸信息(尺寸)怎么办?如果我们可以写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!

答案 1 :(得分:0)

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