我使用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)
}
}
答案 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是存储整数变量指针的指针声明。