Home > front end >  stack smashing detected when trying to get to typedef two dinatial array that the adress store insid
stack smashing detected when trying to get to typedef two dinatial array that the adress store insid

Time:05-15

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)

CodePudding user response:

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.

CodePudding user response:

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);
        }
    }
}
  • Related