【问题标题】:Running out of memory.. How?内存不足..怎么办?
【发布时间】:2010-05-08 02:40:28
【问题描述】:

我正在尝试为特定谜题编写求解器。它试图通过一次尝试所有可能的移动来找到解决方案,直到找到解决方案。第一个版本试图通过不断尝试移动直到失败,然后回溯来解决它的深度优先问题,但结果证明这太慢了。我已经使用队列结构将其重写为广度优先,但我在内存管理方面遇到了问题。

以下是相关部分:

int main(int argc, char *argv[])
{
    ...
    int solved = 0;
    do {
        solved = solver(queue);
    } while (!solved && !pblListIsEmpty(queue));
    ...
}

int solver(PblList *queue) {
    state_t *state = (state_t *) pblListPoll(queue);

    if (is_solution(state->pucks)) {
        print_solution(state);
        return 1;
    }

    state_t *state_cp;
    puck new_location;
    for (int p = 0; p < puck_count; p++) {
        for (dir i = NORTH; i <= WEST; i++) {
            if (!rules(state->pucks, p, i)) continue;
            new_location = in_dir(state->pucks, p, i);
            if (new_location.x != -1) {
                state_cp = (state_t *) malloc(sizeof(state_t));
                state_cp->move.from = state->pucks[p];
                state_cp->move.direction = i;
                state_cp->prev = state;
                state_cp->pucks = (puck *) malloc (puck_count * sizeof(puck));
                memcpy(state_cp->pucks, state->pucks, puck_count * sizeof(puck)); /*CRASH*/
                state_cp->pucks[p] = new_location;
                pblListPush(queue, state_cp);
            }
        }
    }

    free(state->pucks);

    return 0;
}

当我运行它时,我得到了错误:

ice(90175) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Bus error

错误发生在迭代 93,000 左右。 据我所知,错误消息来自 malloc 失败,而总线错误来自之后的 memcpy。

我很难相信我的内存已经用完了,因为每个游戏状态只有约 400 字节。然而,这似乎是正在发生的事情,因为活动监视器报告说它在崩溃之前正在使用 3.99GB。我使用http://www.mission-base.com/peter/source/ 作为队列结构(它是一个链表)。

显然我在做一些愚蠢的事情。有什么建议吗?

【问题讨论】:

  • 你在三个方面自相矛盾。 1. 400 字节,2. 3.99GB,3. 93000*puck_count*sizeof(puck) 分配(这比 400 字节多得多)。你实际观察到的行为是什么?完成后忘记free内存了吗?
  • 每个游戏状态大约是 400 字节,但它会复制很多,显然足以填满 4 GB 的内存。我没有释放所有的旧内存(我释放了旧的 puck-arrays 但仅此而已),但那是因为我需要它来跟踪到目前为止所采取的动作。
  • @maxdj:那你如何解释矛盾#3?
  • @Billy:我的意思是外循环的 93000 次迭代。外部循环的每次迭代都会产生多个 malloc,具体取决于游戏状态中有效移动的数量。
  • 您有 2 个 malloc,但只有 1 个空闲。

标签: c malloc


【解决方案1】:

检查malloc 的结果。如果是NULL,您可能需要打印出该队列的长度。

另外,您发布的代码 sn-p 不包含任何 frees...

【讨论】:

  • 结果为 NULL。队列的长度约为 900 万(天...)
  • @maxdj:嗯,9m * 400 = ~3.6b,这是你所期望的,对吧?
  • 好吧 400 字节 * 9e6 会关闭以耗尽内存。您是否曾经从队列中删除项目?广度优先算法实际上使用的内存可能比您所能提供的要多。您可能需要将工作拆分为更多部分。
  • @James:是的,我想是的。问题是我不能完全释放以前的状态,因为我需要知道采取了哪些步骤来解决问题。
  • @maxdj 然后你要么需要回到深度优先搜索,要么使用某种修剪过的搜索树。 A* 可能。
【解决方案2】:

你需要free()你在完成后手动分配的内存;动态内存不只是“释放自己

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 2015-05-11
    • 2011-05-31
    • 2019-10-10
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多