I'm writing a numpy out of C. I basically assign some attribute from a parent struct to a variable p_ref before I deallocate the parent struct, and then use that variable in a conditional statement later. This causes a core dumped. However, if I don't assign it to the variable but just use the attribute at the end, it does not segfault. I'm confused they seem to be the same. Also, I'm not sure how the second method works because it tries to reference a attribute from an already deallocated struct.
Here is my header for matrix struct:
typedef struct matrix {
    int rows; // number of rows
    int cols; // number of columns
    double* data; // pointer to rows * columns doubles
    int ref_cnt; // How many slices/matrices are referring to this matrix's data
    struct matrix *parent; // NULL if matrix is not a slice, else the parent matrix of the slice
    int is_1d;
    int is_slice;
    int offset;
} matrix;
double rand_double(double low, double high);
void rand_matrix(matrix *result, unsigned int seed, double low, double high);
int allocate_matrix(matrix **mat, int rows, int cols);
int allocate_matrix_ref(matrix **mat, matrix *from, int offset, int rows, int cols);
void deallocate_matrix(matrix *mat);
double get(matrix *mat, int row, int col);
void set(matrix *mat, int row, int col, double val);
void fill_matrix(matrix *mat, double val);
int add_matrix(matrix *result, matrix *mat1, matrix *mat2);
int sub_matrix(matrix *result, matrix *mat1, matrix *mat2);
int mul_matrix(matrix *result, matrix *mat1, matrix *mat2);
int pow_matrix(matrix *result, matrix *mat, int pow);
int neg_matrix(matrix *result, matrix *mat);
int abs_matrix(matrix *result, matrix *mat);
And here are the two versions of my code for deallocating matrix:
Version 1
void deallocate_matrix(matrix *mat) {        
    if (mat == NULL) { return; }
    mat->ref_cnt = mat->ref_cnt - 1;
    if (mat->ref_cnt > 0) { return; }
    int p_ref = mat->parent->ref_cnt;
    if (mat->parent) {
        deallocate_matrix(mat->parent);
    }
    if (!(mat->is_slice) && mat->ref_cnt == 0) {
        free(mat->data);
    } else if (p_ref == 1) {
        free(mat->data);
    }
    free(mat);
    return;
}
Version 2
void deallocate_matrix(matrix *mat) {
    if (mat == NULL) { return; }
    mat->ref_cnt = mat->ref_cnt - 1;
    if (mat->ref_cnt > 0) { return; }
    if (mat->parent) {
        deallocate_matrix(mat->parent);
    }
    if (!(mat->is_slice) && mat->ref_cnt == 0) {
        free(mat->data);
    } else if (mat->parent->ref_cnt == 1) {
        free(mat->data);
    }
    free(mat);
    return;
}
