Cannot pass my matrix of structs to a function after using malloc function

|▌冷眼眸甩不掉的悲伤 提交于 2021-01-20 10:41:20

问题


I need to create a matrix containing structs. My struct:

typedef struct {
    int a;
    int b;
    int c;
} myStruct;

My method to create matrix:

myStruct (*matrix)[WIDTH] = malloc(HEIGHT * sizeof *matrix);

How can I pass my matrix to a function to do something?


回答1:


In C89, WIDTH must be a constant and you can simply pass the matrix this way:

#include <stdlib.h>

#define WIDTH  5

typedef struct {
    int a;
    int b;
    int c;
} myStruct;

void init_matrix(myStruct matrix[][WIDTH], int height) {
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < WIDTH; j++) {
            matrix[i][j].a = matrix[i][j].b = matrix[i][j].c = 0;
        }
    }
}

int main() {
    int height = 5;
    myStruct (*matrix)[WIDTH] = malloc(height * sizeof *matrix);
    if (matrix) {
        init_matrix(matrix, height);
        ...
        free(matrix);
    }
    return 0;
}

In C99, if variable length arrays (VLAs) are supported, both WIDTH and HEIGHT can be variable but the order of arguments must be changed:

#include <stdlib.h>

typedef struct {
    int a;
    int b;
    int c;
} myStruct;

void init_matrix(int width, int height, myStruct matrix[][width]) {
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            matrix[i][j].a = matrix[i][j].b = matrix[i][j].c = 0;
        }
    }
}

int main() {
    int height = 5;
    int width = 5;
    myStruct (*matrix)[width] = malloc(height * sizeof *matrix);
    if (matrix) {
        init_matrix(width, height, matrix);
        ...
        free(matrix);
    }
    return 0;
}



回答2:


Array calls are decayed to pointers.

When you pass them (arrays) to a function you need to specify all but the first dimension.

The compiler needs all the other dimensions for pointer arithmetic... Here is how you would declare and call in your example:

void f(myStruct p[][WIDTH]);

f(matrix);

When you do p++; inside the function, the compiler knows that the next element is WIDTH * sizeof(myStruct) bytes away in memory.

You could put any value for the in the first [], it would simply be ignored.You have to know the value for the first dimension (probably passed by parameter or controlled as a global variable).




回答3:


You access the 2D array by the incorrect pointer type. The first element of myStruct matrix[5][5] is an array myStruct[5]. Thus you must cast the result of calloc() to a pointer to SO_WIDTH-element-long array.

myStruct (*matrix)[SO_WIDTH] = calloc (SO_HEIGHT * SO_WIDTH, sizeof(myStruct));

Since C99 there is even no need for SO_WIDTH, SO_HEIGHT to be constants.

EDIT

It looks that the question got re-edited. The update answer is:

Use VLA from C99.

void myfunction(int rows, int cols, myStruct matrix[rows][cols]) {
  ...
}


来源:https://stackoverflow.com/questions/65460480/cannot-pass-my-matrix-of-structs-to-a-function-after-using-malloc-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!