Как освободить динамически распределенную память, где каждый индекс также динамически выделяется? - PullRequest
0 голосов
/ 07 февраля 2019

Для проекта я пытаюсь реализовать матричный «класс» в C, но «деструктор» для матрицы выбрасывает исключение.Я не уверен на 100%, почему, хотя я думаю, что это связано с переназначением переменной двум разным динамически размещаемым указателям, а затем попыткой освободить последний дважды.Я не могу использовать C ++ для этого, но я подумал, что постараюсь эмулировать функциональность как можно лучше.

Вот код, я не включаю объявления каких-либо функций или структур, которые необходимо было предопределить:

struct vComplex {
    double* realp;
    double* imagp;
    uint32_t length ; // for bookkeeping
    BOOL(*isreal)(vComplex);
    void(*free)(vComplex*);
    void(*print)(vComplex*);
}; 

struct mComplex { // complex matrix type
    vComplex* columns; // each vComplex represents one column of the mComplex
    uint32_t nCols;
    uint32_t nRows;
    BOOL (*isreal)(mComplex);
    void (*free)(mComplex*);
    void(*print)(mComplex*);
};

vComplex* createVComplex(uint32_t len) {

    vComplex* x = (vComplex*)malloc(sizeof(vComplex));

    x->realp = (double*)malloc(len * sizeof(double));
    x->imagp = (double*)malloc(len * sizeof(double));
    x->length = len;
    x->isreal = &isreal_v;
    x->free = &vComplex_free;
    x->print = &vComplex_print;

    return x;
}

mComplex* createMComplex(uint32_t nRows, uint32_t nCols) {
    mComplex* x = malloc(sizeof(mComplex));
    vComplex* vp;
    x->columns = (vComplex*)malloc(nCols * sizeof(vComplex));
    for (uint32_t i = 0; i < nCols; i++) {
        vp = createVComplex(nRows);
        x->columns[i] = *vp;
    }
    x->nRows = nRows;
    x->nCols = nCols;
    x->isreal = &isreal_m;
    x->free = &mComplex_free;
    x->print = &mComplex_print;

    return x;
}


void vComplex_free(vComplex* x) {
    free(x->realp);
    free(x->imagp);
    free(x); // error occurs here (only when called from mComplex_free)

    return;
}

void mComplex_free(mComplex* x) {
    for (uint32_t i = x->nCols - 1; i >= 0; i--) {
        x->columns[i].free(&x->columns[i]);
    }
    free(x);

    return;
}

vComplex.free вроде бы работает нормально, но mComplex.free выдает исключение.Я предполагаю, что createVComplex создает и возвращает указатель на vComplex, который затем освобождается vComplex.free.createMComplex выделит память для nCols числа vComplex "объектов", которые затем будут освобождены по одному за раз.Затем указатель на массив vComplex будет освобожден и, наконец, указатель на mComplex.Вместо этого я думаю, что первый раз, когда я вызываю vComplex.free внутри mComplex.free, я не могу освободить указатель vComplex по любой причине.

...