指向数组的指针和指向指针的指针的内存分配

时间:2013-11-21 20:57:34

标签: c arrays pointers

我对在堆中为二维数组分配内存的不同方法感兴趣。

在访问指向指针和指向一个或多个维度的数组的指针时,似乎使用了相同的表示法。我希望有人澄清每个人的不同之处和用处。他们都是对的吗?

第一种方法是将数组存储为指针指针:

char **createTable(int r, int c) {
    char **table;
    int i;
    char *offset;
    table = malloc(r * sizeof (char *) + r * c * sizeof (char));
    if (!table) return NULL;
    offset = (char *) table + sizeof (char *) * r;
    for (i = 0; i < r; i++) {
        table[i] = offset + c * i;
    }
    return table;
}

这种方式似乎更快。我想不出把它包装在像其他函数一样的函数中的好方法。

char (*table)[c];
table = (char (*)[c]) calloc(r * c, sizeof (char));

我是否理解即使数组像静态指针一样,数组本身也有多个维度?

我描述的第一种方式是正统的方式吗?

1 个答案:

答案 0 :(得分:1)

不幸的是,似乎没有办法让函数返回一个指向可以正确输入的可变长度数组的指针。你可以这样做:

#include <stddef.h>
#include <stdlib.h>

void* createTable_(size_t r, size_t c) {
  char (*table)[c] = malloc(sizeof(char[r][c]));
  /* do the intialization that you need */
  return table;
}

#define createTable(R, C) ((char(*)[C])createTable_((R), (C)))

int main(int argc, char*argv[]) {
  char (*table)[argc] = createTable(argc, argc);
}

该函数只返回一个void*指针,宏确保正确输入。不幸的是,这样的宏必须两次评估第二个参数,所以要注意副作用。

编辑,针对您提出的其他子问题:

我不会把指针指向模仿多维矩阵的指针方式“正统”,只是过时了。至少对于我所看到的最常见的用途是这样的。

  • 容易出错。你真的必须得到所有的索引计算 对。顺便说一句,你也可以通过使用获得更多可读性 数组上的sizeof,类似于

    malloc(sizeof (char*[r]) + sizeof (char[r][c]))

  • 浪费空间,sizeof(char*[c])部分

  • 它的效率较低,而不是简单的索引计算,它必须做一个额外的间接。

  • 它与使用大量矩阵的其他语言不兼容,例如Fortran。