Если вы хотите выделить всю структуру одним malloc
, вы можете использовать
typedef struct
{
int rows;
int cols;
double data[1];
} Matrix;
. В отличие от других ответов, это позволяет использовать один free
.
Если ваш компилятор поддерживает массивы размера 0, вы также можете использовать double data[0];
.
Начиная с C99 вы можете использовать массив без измерения в структуре: double data[];
, см. https://stackoverflow.com/a/2061038/10622916
Вместо вычисления размера для malloc
путем добавления размера типов полей структуры лучше использовать sizeof
или offsetof
с типом структуры Matrix
, поскольку там могут быть некоторые отступы.(Вероятно, не в вашем случае, но это зависит от реализации компилятора и полей вашей структуры.)
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> // for offsetof
typedef struct
{
int rows;
int cols;
double data[1];
// or with C99: double data[];
} Matrix;
Matrix *initMatrix(int rows, int cols)
{
Matrix *ptr;
double *data;
ptr = (Matrix *)malloc(
offsetof(Matrix, data) // = size of Matrix without double data[1];
// with C99's "double data[];" or with the non-standard
// "double data[0];" you can replace offsetof(...) with: sizeof(Matrix)
+ sizeof(double) * rows * cols); // dynamic array size
if(ptr == NULL) {
perror("malloc failed");
} else {
// save rows and columns for later accessing the matrix
ptr->rows = rows;
ptr->cols = cols;
data = ptr->data;
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
*(data) = 0;
data++;
}
}
}
return ptr;
}
int main(void)
{
Matrix *mptr = initMatrix(2, 2);
// use matrix
// a single free is sufficient with the approach above
free(mptr); mptr = NULL;
return 0;
}
Вместо увеличения указателя data
вы можете вычислить индекс массива
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
ptr->data[i * cols + j] = 0;
}
}
Или для инициализации 0 вы можете использовать memset
memset(ptr->data, 0, sizeof(double) * rows * cols);
или использовать calloc(1, offsetof(Matrix, data) + sizeof(double) * rows * cols);
вместо malloc
, чтобы получить нулевую инициализированную память.