【发布时间】:2011-11-09 08:56:08
【问题描述】:
我有一个蒙特卡罗模拟,它应该运行多次,然后对各个结果进行平均。每次运行后,我想为模拟中需要的东西释放分配的内存。其中一个东西是sites 的数组,其中每个site 是一个结构,它有一个SLE 类型的链表作为一个成员。所以为了全部释放,我先遍历链表,释放每个节点,然后释放sites数组的内存。
SLE * neighbor, * tmp;
int i;
for(i = 0; i < args.nsites_arg; ++i)
{
// free neighbor memory
neighbor = sites[i].neighbors;
while(neighbor)
{
tmp = neighbor->next;
free(neighbor);
neighbor = tmp;
}
}
free((void *)sites);
然而,发生了一些非常奇怪的事情:模拟运行良好一次,然后重新开始。我为sites 重新分配了所有需要的内存,并重写了上面提到的SLEs 的链表。然后,在前一个数组的一些排序操作中,它给了 mit 一个段错误:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000408468 in sortNeighbors (list=0xad0e00) at mc_init.c:485
485 while(temp && temp->next)
当我在上面的 sn-p 中删除 free(neighbor) 时,它工作正常。正如我所说,一切都像第一次运行之前一样重新分配。那么这里会发生什么?我如何收集更多关于真正释放什么以及为什么会发生这种段错误的信息?
编辑:另一个奇怪的事情是,这个排序的开头是这样的:
if (!list || !list->next)
return list;
SLE * temp = list;
// Find halfway through the list
while(temp && temp->next)
{
我明确检查 list 和 list->next 是否存在,那么为什么它会在 while 条件下给出段错误?
Edit2:分配
sites = (Site *) malloc(args.nsites_arg * sizeof (Site));
...
// s is now one element of the sites array
while(siteList)
{
neighbors = (SLE*) malloc(sizeof (SLE));
...
neighbors->next = s->neighbors;
s->neighbors = neighbors;
siteList = siteList->next;
}
【问题讨论】:
-
我担心
(void *)sites在您对free(3)的调用中强制转换——这通常意味着您忘记包含stdlib.h标头,因此无法访问@ 987654337@原型。 -
你是如何声明、分配和初始化
sites的? -
你说你重新分配
sites,但你是否也将所有未使用的东西设置为 NULL - 或者确保所有旧的东西都消失/擦除,所以你没有在任何地方触摸悬空指针? -
你能在 valgrind 之类的东西中运行它吗?希望它能为您提供更多信息。
-
您是否在禁用优化的情况下进行编译?
标签: c memory-management free