我正在使用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)
}
}
我正在使用
malloc
的三指针对3D数组进行编码。
首先,不需要使用对malloc
的多个调用来分配任何数组。事实上,这样做是不正确的,因为单词"array"被认为表示单个连续内存块,即一个分配。我稍后再谈,但首先,你的问题是:
问题:用作
sizeof
的操作数时有什么区别?
答案虽然显而易见,但经常被误解。它们是不同的指针类型,在您的系统中具有相同的大小和表示形式。。。但是它们在其他系统上可能具有不同的大小和表示。重要的是要记住这种可能性,这样你就可以确保你的代码尽可能地可移植。
给定size_t row=3, col=4, dep=5;
,您可以声明一个数组,如下所示:Date array[row][col][dep];
。我知道你在这个问题上发表这样的声明是没有用的。。。请耐心等我一会儿。如果我们printf("%zun", sizeof array);
,它将打印row * col * dep * sizeof (Date)
。它知道数组的全部大小,包括所有维度。。。这就是在分配这样的数组时所需的字节数。
printf("%zun", sizeof ptrDate);
和ptrDate
在您的代码中声明为将产生完全不同的东西,不过。。。它将在系统上生成指针的大小(指向指向Date
的指针,不要与指向Date
的指针或指向Date
指针的pointer混淆)。所有关于维度数量的大小信息(例如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
仍然产生指针的大小(指向Date
的数组[col][dep]),而sizeof *ptrDate
不包含row
维度(因此是上面malloc
中的乘法
free(ptrDate); // Ooops! I must remember to free the memory I have allocated!
int*ptr是存储整数变量地址的指针的声明,int**ptr是保存存储整数变量的指针地址的声明。