释放完全不同的内存后的分段错误

时间:2011-11-09 08:56:09

标签: c memory-management free

我有一个蒙特卡罗模拟,它应该运行多次,然后对各个结果进行平均。每次运行后,我想为模拟中需要的东西释放分配的内存。这个东西的一部分是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)

当我删除上述代码段中的free(neighbor)时,它可以正常工作。正如我所说,所有内容都像第一次运行之前一样重新分配。那么这里发生了什么?我怎么能收集更多关于真正释放的信息以及为什么会发生这种段错误的信息呢?


编辑:另一个奇怪的事情是,这个排序的开头是这样的:

if (!list || !list->next)
    return list;

SLE * temp = list;

// Find halfway through the list
while(temp && temp->next)
{

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

4 个答案:

答案 0 :(得分:1)

如果您使用的是linux,请查看我的回答here。它是关于 valgrind 的,这个工具可以帮助调试段错误,内存泄漏等。

当您通过访问释放的内存获取SIGSEV(根据我的理解你的情况)时,它会告诉您内存被释放的位置 - 它不必被代码段中的free调用释放。

答案 1 :(得分:1)

在搜索错误之前,您可能希望使用已经过良好测试的single or double linked lists

或者,如果您不想打扰内存错误,请链接gc garbage collector(假设模拟的实际计算完成了它应该做的事情)

答案 2 :(得分:0)

Windows的一些更好的商业工具:

  • 净化
  • 投保++

答案 3 :(得分:0)

尝试通过valgrind运行:valgind --tool=memcheck [COMMAND]

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

有关详细信息,请转到Valgrind网站。