2011-11-09 56 views
0

我有一个蒙特卡罗模拟,它应该运行多次,然后平均在单个结果上。每次运行后,我想释放分配的内存以用于模拟中我需要的内容。其中的一块是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) 
{ 

我明确地检查是否listlist->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; 
} 
+0

我担心的是'(无效*)网站'投入到'免费(3)'的通话中 - 通常意味着您忘记了包含'stdlib.h'标头,因此无法访问'free(3)'原型。 – sarnold

+0

你是如何声明,分配和初始化'sites'的? – sarnold

+1

你说你重新分配'网站',但你是否也将所有未使用的东西都设置为NULL - 否则确保所有旧东西都消失/擦除,所以你不会触摸任何地方的悬挂指针? – nos

回答

1

如果你是在Linux上,来看看我的回答here。这是关于Valgrind的,一种工具,帮助调试段错误,内存泄漏等

当你通过访问释放的内存(你的情况我了解)得到SIGSEV,它会告诉你所在的内存被释放了 - 这是没有必要的它是由您的片段中的free调用释放的。

+0

我会尽量在晚些时候挖掘valigrind。感谢您的链接! – janoliver

0

一些windows更良好的商业工具:

  • 净化
  • 投保++
+0

我正在linux上工作,但谢谢。 – janoliver

0

试图通过Valgrind的运行它:valgind --tool=memcheck [COMMAND]

它开箱的,没有什么特别需要的。

欲了解更多信息转到Valgrind网站。

1

在寻找错误之前,您可能需要使用已经实施的良好测试single or double linked lists

或者,如果你不想使用mem错误打扰,对gc garbage collector链接(假设你的模拟的实际计算中做它应该做的)

+0

感谢您的链接。我确实想保持依赖性尽可能简单,因为我仍然在C的学习过程中,我真的很想找到问题并自己解决。另外,自己做记忆管理让你更加小心。至于链表:它们由一些大的结构组成,所以我想我会继续执行。 – janoliver