C:在错误的时间释放malloc'd数组?

时间:2011-04-14 19:43:29

标签: c arrays free

我有struct cell - >

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

我正在使用以下方法释放单元格 - >

void cellFree(struct cell *c)   {
    // Free the keys
    free(c->keys);

    // Free the cell itself.
    free(c);
}

void cellFreeSors(struct cell *cn)  {
    int i;
    for(i = 0; i < 5; i++)  {
        // Free keys
        free(cn[i].keys);
    }
    // Free array
    free(cn);
}

现在,我遇到了一个我创建的malloc'd数组的奇怪问题。 基本上,我试图找到一个单元格的邻居,并使用以下两种方法根据它们的值进行一些处理 - &gt;

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

        // CREATE 5 CELLS
        struct cell *cn = malloc(5 * sizeof (struct cell));
            if (cn == NULL) {
            printf("--> Unable to malloc *cn!\n");
            errno = ENOMEM;
            return NULL;
            }

        for(i = 0; i < 5; i++)  {
            cn[i].keys = malloc(sizeof(struct key));
                if (cn[i].keys == NULL) {
                printf("--> Unable to malloc *cn[%d].keys!\n", i);
                errno = ENOMEM;
                return NULL;
            }
            cellCopyValues(&cn[i], c);
        }

        // MAKE THEM NEIGHBORS
        // PROCESS

        return cn;
    }


    double cellRHS(struct cell *c, struct cell *sstart, struct cell *sgoal, double km, struct cell * prevCell)  {
        // GET NEIGHBORS of c
        struct cell *cn = cellGetSuccessors(c, sstart, sgoal, km);
        double minsum;

        // SOME PROCESS TO UPDATE minsum
        minsum = 5.232111; // SAY

        // Free memory
        cellFreeSors(cn);

        return minsum;
    }

麻烦的是,当我在cellFreeSors()中致电cellRHS()时,我会遇到问题。 这就是这些函数的调用方式..

struct cell *u = cellCreateNew();
u->rhs = cellRHS(u, sstart, sgoal, km, prevCell);
queueAdd(&U, u);

当我尝试打印队列时,这会给我一个分段错误 - &gt;

    QUEUE CONTENTS
    ==================================================================
    F -> 0x2354550
    L - >0x2354550
    (1) [0x2354550] X 50.000000, Y 45.000000    PREV: (nil) NEXT: 0x4014000000000000
Segmentation fault

正如您所看到的,条目的NEXT似乎由于某种原因而被初始化。 执行WITHOUT cellRHS()时相同的代码工作正常.. - &gt;

struct cell *u = cellCreateNew();
queueAdd(&U, u);

    QUEUE CONTENTS
    ==================================================================
    F -> 0x2354550
    L - >0x2354550
    (1) [0x2354550] X 50.000000, Y 45.000000    PREV: (nil) NEXT: (nil)

为什么cellFreeSors()会导致此问题?我对cellRHS范围之外的你产生的邻居毫无用处。我做错了什么?

谢谢..

**编辑 queue_node的结构是

/* QUEUE NODE
 * ----------------------------
 * Contains a struct cell c and
 * reference to next queue_node
 */
struct queue_node   {
    struct cell *c;
    struct queue_node *next;
    struct queue_node *prev;
};

/* PRIORITY QUEUE
 * ----------------------------
 * The queue itself, with first
 * and last pointers to queue_nodes
 */
struct priority_queue   {
    struct queue_node *first;
    struct queue_node *last;
};

queuePrint()方法显示队列内容 - &gt;

void queuePrint(struct priority_queue *q)
{
    printf("\n\n\tQUEUE CONTENTS\n\t==================================================================\n");
    int i = 1;
    struct queue_node *temp = q->first;
    printf("\tF -> %p\n\tL -> %p\n", q->first, q->last);
    while(temp != NULL) {
        printf("\t(%d) [%p]\tX %f, Y %f\tPREV: %p\tNEXT: %p", i, temp, temp->c->x, temp->c->y, temp->prev, temp->next);
        printf("\n");
        temp = temp->next;
        i++;
    }
    printf("\n\n");
}

1 个答案:

答案 0 :(得分:1)

这里有一些建议:

  1. 使用集中式allocCell()和 freeCell()方法。这可以让你 跟踪每个分配的和 完全解除分配的细胞。

  2. 放一个id 在每个细胞上。再次,这允许 详细的追踪。你可以编译它 一种生产方式和另一种方式 如果空间有问题,请进行调试。

  3. 为单元格写入跟踪例程, 看你的惯例是唯一的 释放分配的细胞,任何 细胞只被释放一次,等等 甚至可以写一个哈希表 存储已分配和的ID 释放细胞(当然只是在期间) debug)和写入验证 检查。

  4. 你可能会去 如果你再次遇到内存错误 不要这样做。

  5. 即使您这样做,也会再次遇到内存错误,但这些工具可以帮助您在下次更快地跟踪它。

  6. 切换到C#或java并且不释放任何内容:)