'Cannot restart typedef'd 2D array whose address is saved in struct

I have this typedef and struct:

typedef double mat[MAT_SIZE][MAT_SIZE];

typedef struct matList {
    char *name;
    mat *matrix;
} matList;

and I create an array of pointers to my structure:

    mat MAT_A, MAT_B, MAT_C, MAT_D, MAT_E, MAT_F;
    matList *mats[MAT_COUNT];
    int i;
    
    for (i = 0; i < MAT_COUNT; i++) {
        mats[i] = NULL;
    }
    mats[0] = create_mat("MAT_A", &MAT_A);
    mats[1] = create_mat("MAT_B", &MAT_B);
    mats[2] = create_mat("MAT_C", &MAT_C);
    mats[3] = create_mat("MAT_D", &MAT_D);
    mats[4] = create_mat("MAT_E", &MAT_E);
    mats[5] = create_mat("MAT_F", &MAT_F);

my create_mat function look like this:

matList *create_mat(char *name, mat *curMat) {
    matList *tempMat = (matList *)malloc(sizeof(matList));

    if (tempMat != NULL) {
        tempMat->name = name;
        tempMat->matrix = curMat;
        return tempMat;
    }
    free(tempMat);
    tempMat = NULL;
    return NULL;
}

and I am tying to get to the two dimensional array and put 0 in all the cells but it doesn't work:

  • sometimes I have a core dump (but it succeeds putting the 0)
  • sometimes I don't get a core dump but I don't have zero in all the cells
void restart_mat(matList *mats[]) {
    int i, j, k;

    if (mats == NULL) {
        return;
    }

    for (k = 0; k < MAT_COUNT; k++) {
        if (mats[k] != NULL) {
            for (i = 0; i < MAT_SIZE; i++) {
                for (j = 0; j < MAT_SIZE; j++) {
                     mats[k]->matrix[0][i][j] = 0;
                }
            }
        }
    }
}


Solution 1:[1]

The 2D arrays MAT_A, MAT_B, MAT_C, MAT_D, MAT_E, MAT_F are defined as local objects with automatic storage in the function that calls create_mat. A pointer to these arrays is set in the allocated matList structure. These arrays must no longer be referenced after the function returns.

Unless there is a compelling reason to allocate the 2D arrays and the matList structures separately, you should define the matrix as a struct member instead of a pointer:

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

typedef double mat[MAT_SIZE][MAT_SIZE];

typedef struct matList {
    const char *name;
    mat matrix;
} matList;

void init_mat(mat m) {
    for (int i = 0; i < MAT_SIZE; i++) {
        for (int j = 0; j < MAT_SIZE; j++) {
            m[i][j] = 0;
        }
    }
}

matList *create_mat(const char *name) {
    matList *tempMat = malloc(sizeof(*tempMat));
    if (tempMat != NULL) {
        tempMat->name = name;
        init_mat(tempMat->matrix);
    }
    return tempMat;
}

// return non zero if successful
int allocate_matList(matList *mats) {
    for (int i = 0; i < MAT_COUNT; i++) {
        mats[i] = NULL;
    }
    mats[0] = create_mat("MAT_A");
    mats[1] = create_mat("MAT_B");
    mats[2] = create_mat("MAT_C");
    mats[3] = create_mat("MAT_D");
    mats[4] = create_mat("MAT_E");
    mats[5] = create_mat("MAT_F");
    return mats[0] && mats[1] && mats[2] &&
           mats[3] && mats[4] && mats[5];
}

void restart_matList(matList *mats) {
    if (mats != NULL) {
        for (int k = 0; k < MAT_COUNT; k++) {
            if (mats[k] != NULL)
                init_mat(mats[k]->matrix);
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1