2013-11-21 242 views
2

我感兴趣的是不同的方式来分配内存在堆中的二维数组。内存分配指针指向数组和指针指针

当访问指向指向一个或多个维度数组的指针和指针的指针时,似乎使用相同的符号。我希望能有人澄清每个人的差异和用处。他们都对吗?

这个第一方式将阵列作为指针存储到指针:

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

为什么不只是'char table [r] [c]'?我猜你的意图是,将有可能从分配它的函数返回指针?在问题中明确说明这一点可能很有用,所以我们知道你为什么不只是在执行'char table [r] [c];' –

+0

更具体地说:你不能返回'table',其中'table '是'char(* table)[c];'来自返回'char **'的函数。铿锵:'不兼容的指针类型返回'char(*)[c]'从结果类型'char **'的函数' –

回答

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*和宏确保正确的打字。不幸的是,这样一个宏必须对第二个参数进行两次评估,所以要小心副作用。

编辑,为你问问其他子问题:

我不会把指针模拟多维矩阵“正统”的指针方式,只是过时。至少对于我所见过的最常用的东西来说是如此。

  • 这很容易出错。你真的必须得到所有索引计算 正确的。 BTW有你也可以得到更多的东西可读,通过使用 sizeof阵列上,像

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

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

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

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

+0

这是你回答的部分的一个很好的答案,但比较两种方法的部分将不胜感激。 – niic