如何使用通过引用C中的函数传递的指针来malloc 2d锯齿状数组

时间:2012-10-18 15:46:56

标签: c function malloc multidimensional-array

我在main()块中声明了一个2D锯齿状数组。这将被传递给一个函数,以便为其分配内存。以下是最简化的情况,它会在运行时编译但崩溃。我哪里错了?

#include <stdio.h>
#include <stdlib.h>

void alloc2d(double ***p);


int main () {

    double **data;

    alloc2d(&data);
    printf("Before assign to data\n");
    data[0][0] = 0.1;
    printf("After assign to data\n");
    free(data);
}


void alloc2d(double ***p) {

    int i, n, m;

    // Get some dynamically assigned sizes
    printf("Enter size: ");
    scanf("%d %d", &n, &m);    
    // Now allocate
    *p = malloc(n * sizeof(double*));
    for (i = 0; i < n; i++) {
        *p[i] = malloc(m * sizeof(double));
    }
    printf("End of alloc2d\n");
}

当我输入较低的数字(即&#39; 1 1&#39;)时会读取值但会崩溃,但是当我输入高数字时会崩溃(即&#39; 10 10&#39;)。

3 个答案:

答案 0 :(得分:6)

你做了一个非常简单的语法错误

*p[i] = (double*)malloc(m * sizeof(double));

应该是

(*p)[i] = (double*)malloc(m * sizeof(double));

这是因为在C中,[]运算符的优先级高于*。 所以当你输入*p[i]时, 它被翻译成**(p + i)

这意味着:您要求编译器通过i * sizeof(double**)偏移p的地址来计算地址,这显然不是您真正想要的。

因此,为了强制编译器首先取消引用p,只需用括号括住*p

答案 1 :(得分:3)

运营商优先权就是答案。 *p[i]相当于*(p[i])。这使您可以访问位于data指针之后的内存,这将破坏堆栈上的其他一些变量,或者完全崩溃。

您正在寻找(*p)[i],这将是新分配的数组中的第i个条目。

答案 2 :(得分:0)

您的alloc2d()分配的内容实际上不是2D数组,但是:

  • 1个1-n n长指针数组
  • n 1D m长的双打阵列

只有在编译时才能知道除最后一个维之外的所有维数时,才能使用C中的多维数组:

double a[5][11];

也许,这个程序可以帮助你理解......注意,COLUMNS是一个编译时常量,即使行是一个运行时变量:

#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <err.h>

typedef double  myrow_t[11]; /* 11 columns */
#define COLUMNS (sizeof(myrow_t)/sizeof(double))

static unsigned
alloc2d(myrow_t **pd)
{
unsigned int rows;

printf("Enter the number of rows: ");
while (scanf("%u", &rows) != 1)
    printf("\ninvalid input, please, try again: ");

*pd = malloc(rows * sizeof(**pd));
if (*pd == NULL)
    err(EX_TEMPFAIL, "Out of memory");

return rows;
}

int
main()
{
myrow_t     *d;
unsigned int     row, column, rows;

rows = alloc2d(&d);

for (row = 0; row < rows; row++)
    for (column = 0; column < COLUMNS; column++)
        d[row][column] = row * column;

for (row = 0; row < rows; row++) {
    printf("Row %3d:\t", row);
    for (column = 0; column < COLUMNS; column++)
        printf("%.0f\t", d[row][column]);
    puts("");
}

free(d);
return 0;
}