Как правильно освободить определенные элементы массива malloc? - PullRequest
2 голосов
/ 14 апреля 2011

Я использую следующую структуру и методы:

struct cell {
    double x, y, h, g, rhs;
    struct key *keys;
};

void cellFree(struct cell *c)   {
    free(c->keys);
    c->keys = NULL;
    free(c);
    c = NULL;
}

void cellCopyValues(struct cell *targetcell, struct cell *sourcecell)   {
    targetcell->x = sourcecell->x;  
    targetcell->y = sourcecell->y;  
    targetcell->h = sourcecell->h;  
    targetcell->g = sourcecell->g;  
    targetcell->rhs = sourcecell->rhs;  
    keyCopyValues(targetcell->keys, sourcecell->keys);
}

struct cell * cellGetNeighbors(struct cell *c, struct cell *sstart, struct cell *sgoal, double km)  {
    int i;

    // CREATE 8 CELLS
    struct cell *cn = malloc(8 * sizeof (struct cell));

    for(i = 0; i < 8; i++)  {
        cn[i].keys = malloc(sizeof(struct key));
        cellCopyValues(&cn[i], c);
    }


    return cn;
}

struct cell * cellMinNeighbor(struct cell *c, struct cell *sstart, struct cell *sgoal, double km)   {
    // GET NEIGHBORS of c
    int i;
    struct cell *cn = cellGetNeighbors(c, sstart, sgoal, km);
    double sum[8];
    double minsum;
    int mincell;

    cellPrintData(&cn[2]);

    // *** CHOOSE A CELL TO RETURN
    mincell = 3; // (say)


    // Free memory
    for(i = 0; i < 8; i++)  {
        if(i != mincell)    {
            cellFree(&cn[i]);
        }
    }

    return (&cn[mincell]);
}

Когда я вызываю cellMinNeighbor(), мне нужно вернуть одного из 8 порожденных соседей (из cellGetNeighbors()) на основе критериев выбора - однако текущий метод, который я применил к свободным другим элементам, кажется, давая мне следующую ошибку:

*** glibc detected *** ./algo: free(): invalid pointer: 0x0000000001cb81c0 ***

Что я делаю не так? Спасибо.

1 Ответ

5 голосов
/ 14 апреля 2011

Вы выделяете массив, а затем пытаетесь освободить определенные элементы.

Ваш cn выделен как массив из 8 struct cell, но вы на самом деле пытаетесь освободить &cn[0], &cn[1], &cn[2], который на самом деле не был выделен с помощью malloc, который требует своего свободного.

Вы должны освобождать только те указатели, которые вы получили с помощью malloc, и одно хорошее правило, которое следует помнить, состоит в том, что число освобождений должно соответствовать количеству malloc.

В этом случае вы используете malloc cn и отдельные ключи, но не &cn[1] и т. Д. Поэтому освобождение их является ошибкой.

Если вы посчитаете malloc, у вас есть 9, но освобождает 16.

...