【发布时间】: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 个空闲。