我有一个蒙特卡罗模拟,它应该运行多次,然后平均在单个结果上。每次运行后,我想释放分配的内存以用于模拟中我需要的内容。其中的一块是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
提到的链接列表。然后,在原阵列上的一些排序操作,它给麻省理工学院段错误:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000408468 in sortNeighbors (list=0xad0e00) at mc_init.c:485
485 while(temp && temp->next)
当我在上面的代码片段删除free(neighbor)
,它工作正常。正如我所说的,一切都是重新分配的,就像第一次运行之前一样。那么这里发生了什么?我如何收集更多关于什么是真正释放的信息以及为什么会出现这种段错误?
编辑:另一个奇怪的是,这个排序的开头是这样的:
if (!list || !list->next)
return list;
SLE * temp = list;
// Find halfway through the list
while(temp && temp->next)
{
我明确地检查是否list
和list->next
存在,那么,为什么给人的段错误而条件?
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;
}
我担心的是'(无效*)网站'投入到'免费(3)'的通话中 - 通常意味着您忘记了包含'stdlib.h'标头,因此无法访问'free(3)'原型。 – sarnold
你是如何声明,分配和初始化'sites'的? – sarnold
你说你重新分配'网站',但你是否也将所有未使用的东西都设置为NULL - 否则确保所有旧东西都消失/擦除,所以你不会触摸任何地方的悬挂指针? – nos