【问题标题】:SIGTRAP when calling the free() function调用 free() 函数时的 SIGTRAP
【发布时间】:2014-12-21 22:44:30
【问题描述】:

我在尝试释放动态创建的数组时收到 SIGTRAP 信号,但不知道原因。

我是这样分配数组的:

int* visited = (int*) malloc( l.nodeCount * sizeof(int));

(l.nodeCount 是一个整数。在程序的实例中我得到这个错误,它设置为 12。)

当我尝试free(visited) 时,我在调试器中收到 SIGTRAP 信号。

整个函数就是这个:

int Graph_GetSmallestPathCount(AdjacencyList l, int destination){

//One path if destination is root
if(destination == 0) return 1;

if(l.nodeCount == 0)
    return 0;

Queue reading = Queue_NewQueue();
Queue storing = Queue_NewQueue();

/*Allocates visited array*/
int* visited = (int*) calloc( l.nodeCount, sizeof(int));

/*Visited array initialization*/
int i;
for(i = 0; i < l.nodeCount; i++)
    visited[i] = 0;

/*Marks root node and enqueues it*/
visited[0] = 1;
Queue_Enqueue(&reading, 0);

//While there are nodes to read
while(!Queue_IsEmpty(reading))
{

    //Dequeues a node
    int v = Queue_Dequeue(&reading);

    //Gets it's adjacency list
    List* currentList = AdjacencyList_GetAdjacentNodes(l, v);
    listCell* auxCell = currentList->head->next;

    //While there are nodes in it's adjacency list
    while(auxCell != NULL){

        //Enqueues it if it has not been visited
        if(visited[auxCell->data] == 0){
            Queue_Enqueue(&storing, auxCell->data);
        }

        //Adds to the paths to that node
        visited[auxCell->data] += visited[v];

        auxCell = auxCell->next;
    }

    //When the queue ends
    if(Queue_IsEmpty(reading)){

        //If the destination has been reached, return
        if(visited[destination] > 0){
            Queue_Destroy(&reading);
            Queue_Destroy(&storing);
            return visited[destination];
        }
        else{
            //Switch queues
            Queue_Destroy(&reading);

            reading = storing;
            storing = Queue_NewQueue();
        }
    }

}

//Destination has not been reached before end of algorithms. Deallocate everything and return 0
free(visited);
Queue_Destroy(&reading);
Queue_Destroy(&storing);

return 0;

}

很抱歉缺少 cmets,我是在运行中完成的,但没有放入任何内容。也很抱歉 printf 过载,我在试图查明问题时将它们放在那里。 编辑:我清理了一下。

奇怪的是,该程序适用于某些输入,而不适用于其他输入。

希望有人能帮帮我=D

【问题讨论】:

  • 也许你的代码中的某些东西弄乱了堆。双重free() 也可能导致该错误。
  • auxCell-&gt;datavisited[auxCell-&gt;data] += visited[v]; 中的值可能等于或大于l.nodeCount
  • 不能,因为它只能是图中的一个节点。我已经确定了。
  • 尝试在每次为visited[n] 分配某些内容时输出[] 数字的值,以便查看是否超过了分配的内存。我猜这在某个时候会发生。如果使用 calloc,则不需要初始化数组,因为它已经将分配的内存初始化为全零。
  • 你可能有一个严重的memory corruption。如果可用,请使用valgrind

标签: c free dynamic-memory-allocation


【解决方案1】:

我无法告诉您为什么会收到 SIGTRAP,因为您还没有发布最小示例。

但是,我可以告诉你如何找出自己:

  1. 使您的程序可读。每行使用一条指令。 indent 工具是您的朋友。当然,这不会修复错误,但它会让您更容易找到它。

  2. 不要那样malloc。无需强制转换malloc 的返回值,并且使用calloc(l.nodeCount, sizeof (int)); 或类似的东西更易读。

  3. SIGTRAP 的实际含义是您遇到了断点指令。毫无疑问,实际发生的事情是您跳到了一些不是您的代码的东西,并且可能根本不是代码,而是包含断点的二进制代码。为什么会这样?正常的原因是内存损坏,尤其是堆栈损坏。我猜free() 正在破坏它自己的堆栈。我猜这是因为您正在(某处)写入您分配的内存之外的内存。要对此进行测试,请使用malloc()/calloc() 运行您的程序,然后紧跟free()exit(0)。如果这有效,您就知道问题出在您之间。

  4. 我们不知道您之间在做什么,因为您还没有(谢天谢地)发布完整的程序,但请尝试在 valgrind 下运行它。当您收到超出范围的写入时,valgrind 通常会捡起它。修复每个valgrind 警告。这并不能保证有一个解决方案,但根据我的经验,95% 的时间都会找到一个。

  5. 另请注意,return visited[destination]; 似乎在没有 free()-ing visited 的情况下退出函数,因此这是内存泄漏。

【讨论】:

  • 正如我所说,对于所有这些打印件感到抱歉。它们是每行多于一条指令的唯一场合。
  • 那里,我清理了一下。
【解决方案2】:

首先,不要这样调用 malloc() 。 l.nodeCount * sizeof(int) 可能会超过 INT_MAX,您可能会遇到安全漏洞,或者如果幸运的话,会崩溃。

改为使用calloc(l.nodeCount, sizeof(int))

您还应该检查malloccalloc 的返回值是否为NULL,以防您的程序分配的内存不足。

【讨论】:

    【解决方案3】:

    找到答案。确实有可能在特定情况下创建数组时少一个元素。我的错。

    感谢所有帮助过的人=D

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      • 2015-07-26
      • 2020-04-18
      • 1970-01-01
      • 2012-01-25
      相关资源
      最近更新 更多