C: блок кучи ### изменен на ### после запрошенного размера ### - PullRequest
0 голосов
/ 09 июля 2020

Итак, я сохраняю 2D-динамику c Массив в матричную структуру:

struct Matrix {
    int ncol;
    int nrow;
    double **mat;
};
typedef struct Matrix Matrix;

Затем у меня есть функция, которая берет содержимое из 2D-массива и сохраняет его в матрицу:

// Initializes matrix mat whose values are the passed in 2D array
// Made Matrix **mat a double pointer so that I can initialize the Matrix *pointer from Main
void matrix_initializeFromArray(Matrix **mat, int nrow, int ncol, double array[][ncol]) {
    (*mat) = (Matrix*) malloc(sizeof(Matrix*));
    (*mat)->mat = (double**) malloc(nrow*sizeof(double*));
    for(int i = 0; i < nrow; i++) {
        (*mat)->mat[i] = (double*) malloc(ncol*sizeof(double*));
        for(int j = 0; j < ncol; j++) { // intialize all values to array values
            (*mat)->mat[i][j] = array[i][j];
        }
    }
    (*mat)->ncol = ncol;
    (*mat)->nrow = nrow;
}

Где это деструктор для матрицы:

// Destructor
void matrix_destructor(Matrix **mat) {
    for(int i = 0; i < (*mat)->nrow; i++) {
        free((*mat)->mat[i]);
    }
    free((*mat)->mat);
    free(*mat);
}

Небольшой пример:

void main() {
Matrix *temp;
    double array[1][1];
    array[0][0] = 34;
    matrix_initializeFromArray(&temp, 1, 1, array);
    matrix_print(temp);
    matrix_destructor(&temp);
}

Этот код обычно выполняется на gdb и valgrind в моем Linux Ubuntu, но по какой-то причине он создает эту ошибку, когда я запускаю его на Windows.

warning: HEAP[a.exe]:
warning: Heap block at 00B51710 modified at 00B5171C past requested size of 4

Я пробежал через gdb на Windows, и это происходит в этой строке в деструктор на первом l oop: free((*mat)->mat[i]);

Любая помощь?

1 Ответ

1 голос
/ 09 июля 2020

Я упростил ваш код, матрица_print отсутствует Проблема была с malloc, когда вы выделяете что-то, вы получаете указатель на память, например, malloc(sizeof(double)); возвращает указатель на область памяти, которая может хранить двойную, поэтому double *

malloc(sizeof(double*)); возвращает указатель на память, которая может хранить указатель на double, поэтому double ** `

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

struct Matrix {
    int ncol;
    int nrow;
    double **mat;
};
typedef struct Matrix Matrix;

void matrix_initializeFromArray(Matrix *mat, int nrow, int ncol, double array[][ncol]) {
    mat->ncol = ncol;
    mat->nrow = nrow;
    mat->mat = malloc(nrow * sizeof(double*));
    for(int i = 0; i < nrow; i++) {
        mat->mat[i] = malloc(ncol*sizeof(double));
        for(int j = 0; j < ncol; j++) { // intialize all values to array values
            mat->mat[i][j] = array[i][j];
        }
    }
}

void matrix_wipe(Matrix *mat) {
    for(int i = 0; i < mat->nrow; i++) {
        free(mat->mat[i]);
    }
    free(mat->mat);
}

int main(void) {
    Matrix temp;
    double array[1][1];
    array[0][0] = 34;
    matrix_initializeFromArray(&temp, 1, 1, array);
    matrix_wipe(&temp);
    return 0;
}
...