'stack smashing detected when trying to get to typedef two dinatial array that the adress store inside struct

i have this typedef of two dinantial array, and strust the keep his adress

typedef double mat[MAT_SIZE][MAT_SIZE];

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

and pointer to arry of matList

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);

i want to have a function that ill be able to get to the mat and put valuse inside the two dimantial array i wirte this one

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)[i][j] = 0;
                }
            }
        }
    }
}

it dose what i ask to but then i get -

*** stack smashing detected ***: ./mainmat terminated
Aborted (core dumped)


Solution 1:[1]

The data member matrix has the pointer type double ( * )[MAT_SIZE][MAT_SIZE].

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

So the pointer matrix must point to a valid two-dimensional array of the type double [MAT_SIZE][MAT_SIZE] and dereferencing the pointer you will get lvalue of the array. Thus the loops will look like

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)[i][j]=0;
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
            }
          }
 }
}

Instead of the statement

( *mats[k]->matrix)[i][j]=0;

you may also write

mats[k]->matrix[0][i][j]=0;

As for this statement

*(mats[k]->matrix)[i][j]=0;

then it is equivalent to

*(mats[k]->matrix[i][j] ) = 0;

because the postfix subscript operator [] has a higher precedence than the dereference operator *.

Pay attention to that the function create_mat must return a pointer to a dynamically allocated object of the type matList.

Solution 2:[2]

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
Solution 2 chqrlie