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

标签 c pointers memory malloc

我正在使用三重指针和 malloc 编写一个 3D 数组。我将 (a) 中的 *ptrdate*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)
    }
  }

最佳答案

I am coding a 3D array using triple pointers with malloc.

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

Question: what's the difference when used as the operand of 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 来执行所有这些分配。 .这是一个简单易记的模式,但却是一个难以理解的模式(并且可能适合问另一个问题):

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

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

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

关于c - *ptr 和 **ptr 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29862399/

相关文章:

c - 构建一个数组,其中每个元素都依赖于前一个

c - Fgets 仅返回 '\n' 字符

go - 如何检查接口(interface)是否是指向 slice 的指针

由文字分配的字符串的 C++ 管理

c - 在 C 中将节点 append 到链接列表(我快到了)

c - pthread_create() 调用的函数有多个参数吗?

c - 这段 C 代码的作用是什么? [与函数体代码混淆]

c++ - 函数返回数组地址而不是它的值

c - 不同类型如何存储在内存中

c++ - 如何解决 munmap_chunk() : invalid pointer error in C++