Как правильно выделить память для динамического двумерного массива, заданного двойным указателем в Си?

Есть структура матрицы

typedef struct Matrix {
        size_t rows;
        size_t cols;
    double** val;
} Matrix;

Которая создается данной функцией

Matrix* create_matrix(size_t rows, size_t cols){
    Matrix* neo = malloc(sizeof(Matrix));
    neo -> rows = rows; 
    neo -> cols = cols;
    neo -> val = (double**) malloc(rows * sizeof(double*));
    for (size_t i=0; i<rows; i++){
        neo->val[i] = (double*) malloc(cols * sizeof(double));
        memset(neo->val[i], 0, cols * sizeof(double));
    }
    return neo;
}

А элементы задаются так

int set_elem(Matrix* matrix, size_t row, size_t col, double val){
    matrix->val[row-1][col-1] = val;
    return 0;
}

Но при транспонировании матрицы данной функцией

Matrix* transp(const Matrix* matrix){
    Matrix* neo = create_matrix(matrix->cols, matrix->rows);
    for (size_t i = 1; i < matrix->rows + 1 ; i++){
            for (size_t j = 1; j < matrix->cols + 1; j++){
                set_elem(neo, j, i, matrix->val[j][i]);
        }
    }
    return neo;
}

Компилятор выдает "Ошибка сегментирования (стек памяти сброшен на диск)"

Та же ошибка возникает при создании матрицы из файла

Matrix* create_matrix_from_file(const char* path_file){
    size_t rows;
    size_t cols;
    double val;
    FILE* opened_file = fopen(path_file, "r");
    if (opened_file==NULL){
        printf ("No file");
        return NULL;
    }
    fscanf(opened_file,"%ld", &rows);
    fscanf(opened_file,"%ld", &cols);
    Matrix* neo = create_matrix(rows, cols);
    for (size_t i = 0; i < rows; i++){  
        for (size_t j = 0; j < cols; j++){
            fscanf(opened_file,"%le", &val);
            set_elem(neo, i, j, val);
        }
    }
    fclose(opened_file);
    return neo;
}

Уже несколько раз код переписываю, но все время одна и та же ошибка, есть идеи в чем проблема?


Ответы (1 шт):

Автор решения: Кирилл Малышев
int set_elem(Matrix* matrix, size_t row, size_t col, double val){
    matrix->val[row][col] = val;
    return 0;
}

Matrix* transp(const Matrix* matrix){
    Matrix* neo = create_matrix(matrix->cols, matrix->rows);
    for (size_t i = 0; i < matrix->rows ; i++){
            for (size_t j = 0; j < matrix->col; j++){
                set_elem(neo, j, i, matrix->val[i][j]);
        }
    }
    return neo;
}

Так не будет ошибки, но вам нужно переписать set_elem на swap_elem, т.к. иначе значения будут затираться.

→ Ссылка