简体   繁体   English

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

[英]How to malloc a 2d jagged array using a pointer passed by reference to a function in C

I have a 2D jagged array declared in my main() block. 我在main()块中声明了一个2D锯齿状数组。 This is to be passed to a function to have memory allocated to it. 这将被传递给一个函数,以便为其分配内存。 The following is the most reduced case which compiles but crashes when it runs. 以下是最简化的情况,它会在运行时编译但崩溃。 Where am I going wrong? 我哪里错了?

#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");
}

This reads the values but crashes when I enter low numbers (ie '1 1') but crashes when I enter high numbers (ie '10 10'). 这会读取值,但是当我输入低数字(即'1 1')时会崩溃,但是当我输入高数字(即'10 10')时会崩溃。

You made a very simple syntax error 你做了一个非常简单的语法错误

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

should really be 应该真的

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

This is because in C, [] operator has higher precedence than *. 这是因为在C中,[]运算符的优先级高于*。 So when you type *p[i] , it is translated into **(p + i) . 所以当你输入*p[i] ,它被翻译成**(p + i)

This means: you are asking the compiler to calculate the address by offsetting the address of p by i * sizeof(double**) , which is clearly not what you actually want. 这意味着:你要求编译器通过将p的地址偏移i * sizeof(double**)来计算地址,这显然不是你真正想要的。

So, in order to force the compiler to dereference p first, simply surroud *p with brackets. 因此,为了强制编译取消引用p个第一,只是surroud *p与支架。

Operator precedence is the answer. 运算符优先级就是答案。 *p[i] is equivalent to *(p[i]) . *p[i]相当于*(p[i]) This makes you access memory that lies right after the data pointer, which will either corrupt some other variables on the stack, or crash completely. 这使您可以访问位于data指针之后的内存,这将破坏堆栈上的其他一些变量,或者完全崩溃。

You were looking for (*p)[i] , which will be the i-th entry in the newly allocated array. 您正在寻找(*p)[i] ,这将是新分配的数组中的第i个条目。

What your alloc2d() allocates is not really a 2D array, but: 您的alloc2d()分配的内容实际上不是2D数组,但是:

  • 1 1D n-long array of pointers to double 1个1-n n长指针数组
  • n 1D m-long arrays of doubles n个1D长的双打阵列

Multi-dimensional arrays in C are only possible, if all but the last of the dimensions are known at compile-time: C中的多维数组只有在编译时才能知道除最后一个维之外的所有维数:

double a[5][11];

Maybe, this program can help you understand... Note, how COLUMNS is a compile-time constant, even if rows is a run-time variable: 也许,这个程序可以帮助你理解......注意,COLUMNS是一个编译时常量,即使rows是一个运行时变量:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM