A popular naming convention is to prefix all the operations with the type name. That means they are predictable, and they fall together alphabetically when listing all symbols
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
struct Array {
double **data;
size_t rows;
size_t cols;
};
struct Array *NewArray*array_calloc(const size_t rows, const size_t cols)
{
struct Array *array = malloc(sizeof *array);
if (!array) {
return array;
}
array->rows = rows;
array->cols = cols;
array->data = malloc(rows * sizeof *array->data);
if (!array->data) {
free(array);
return NULL;
}
for (size_t i = 0; i < rows; ++i) {
array->data[i] = malloc(cols * sizeof *array->data[i]);
if (!array->data[i]) {
while (i-->0) {
free(array->data[i]);
}
free(array->data);
free(array);
return NULL;
}
for (size_t j = 0; j < cols; ++j) {
array->data[i][j] = 0.0;
}
}
return array;
}
void FreeArrayarray_free(struct Array *array)
{
if (array) {
assert (array->data);
for (size_t i = 0; i < array->rows; ++i) {
free(array->data[i]);
}
free(array->data);
free(array);
}
}
void PrintArrayarray_print(const struct Array *array)
{
for (size_t i = 0; i < array->rows; ++i) {
for (size_t j = 0; j < array->cols; ++j) {
printf("%.2lf2f ", array->data[i][j]);
}
printf("\n");
}
return;
}
#include <errno.h>
#include <string.h>
int main(void)
{
struct Array *M*a = NewArrayarray_calloc(2, 4);
if (!Ma) {
fputs(strerror(ENOMEM), stderr);
return EXIT_FAILURE;
}
PrintArrayarray_print(Ma);
FreeArrayarray_free(Ma);
}
#include <stdio.h>
#include <stdlib.h>
struct Array {
double *data;
size_t rows;
size_t cols;
};
/* private helper */
static double *array_element(const struct Array *a, size_t row, size_t col)
{
return a->data + row * a->cols + col;
}
/* public interface */
double array_value(const struct Array *a, size_t row, size_t col)
{
return *array_element(a, row, col);
}
void array_set_value(const struct Array *a, size_t row, size_t col, double v)
{
*array_element(a, row, col) = v;
}
struct Array *NewArray*array_new(const size_t rows, const size_t cols)
{
struct Array *array = malloc(sizeof *array);
if (!array) {
return array;
}
array->data = malloc(sizeof *array->data * rows * cols);
if (!array->data) {
free(array);
return NULL;
}
array->rows = rows;
array->cols = cols;
for (size_t j = 0; j < rows * cols; ++j) {
array->data[j] = 0.0;
}
return array;
}
void FreeArrayarray_free(struct Array *array)
{
if (array) {
free(array->data);
free(array);
}
}
void PrintArrayarray_print(const struct Array *array)
{
for (size_t i = 0; i < array->rows; ++i) {
for (size_t j = 0; j < array->cols; ++j) {
printf("%.2lf2f ", array_value(array, i, j));
}
printf("\n");
}
}
#include <errno.h>
#include <string.h>
int main(void)
{
struct Array *M*a = NewArrayarray_calloc(2, 4);
if (!Ma) {
fputs(strerror(ENOMEM), stderr);
return EXIT_FAILURE;
}
PrintArrayarray_print(Ma);
FreeArrayarray_free(Ma);
}