从导入的 queue.front() 中获取一个奇怪的段错误

Getting a strange seg fault from imported queue.front()

所以我目前正在为我的 CS163 class 开发图形抽象数据类型。该程序的其他所有功能都很棒,但图的深度优先遍历除外。测试时,我添加所有我想要的顶点,然后根据需要连接它们。我检查了一下,一切确实都按应有的方式链接在一起,所以我们可以开始了。我跳转到下面的这个函数,给定朋友(顶点)的名称作为开始。我评论的那行“*current_buddy = myQueue.front();”是我在 GDB 中发现的导致段错误的有问题的代码行。同样使用 GDB,我能够使用 "p myQueue.front()"

成功打印正确的顶点

因此,也许可以通过示例测试来提供更多背景信息。假设我有 a、b、c、d 和 e 点。 a 连接到 c、d 和 e。 b 连接到 c。对于此测试,我想从顶点 "a" 开始。将 a 传递给函数,它使用 find_location 函数找到正确的索引,该函数只是 returns 表示索引整数。然后它将那个顶点推入队列并将该顶点标记为已访问,这样在遍历时,我不会 return 到那个点再次将它推入队列。我创建了一个节点 "current",它附加到 "a" 顶点的边列表中的第一个节点。当它进入第一个循环时,我使用之前创建的顶点 "current_buddy" 指向队列中的第一个对象,即顶点 "a." 这是程序遇到段错误的点并且我这辈子都弄不清楚导致这种情况的那行代码是怎么回事。

"vertex" 和 "node" 都是我创建的结构,我使用的队列来自标准库 #include queue more on the queue bit here if needed 任何和所有信息将不胜感激!显然,由于这是一项学校作业,我不希望有人直接给我答案,但我现在迷路了。

bool graph::breadth_first(char * start)
{
    if(adjacency_list[0].buddy_name == NULL)
        return false;

    int location = find_location(start);
    queue<vertex> myQueue;

    myQueue.push(adjacency_list[location]);
    adjacency_list[location].visited = true;

    node * current = adjacency_list[location].head;
    vertex * current_buddy = NULL;

    while(myQueue.empty() == false)
    {
        *current_buddy = myQueue.front();//THIS LINE SEG FAULTS
        cout << "THIS IS A FRIEND IN THE BREADTH-FIRST TRAVERSAL" << current_buddy->buddy_name << endl;
        current = current_buddy->head;
        myQueue.pop();
        while(current != NULL)
        {
            if(current->connected_buddy->visited == false)
            {
                current_buddy = current->connected_buddy;
                location = find_location(current_buddy->buddy_name);
                myQueue.push(adjacency_list[location]);
                adjacency_list[location].visited = true;
                current = current->next;
            }

        }
    }

    for(int i = 0; adjacency_list[i].buddy_name != NULL; ++i)
    {
        adjacency_list[i].visited = false;
    }
    return true;
}

我不知道这是否会像您预期的那样工作,但一个快速的解决方法可能是使用操作数的地址并实际分配 指针 而不是取消引用它:

current_buddy = &myQueue.front();

(编辑:对于这个问题的第一部分,Joachim 提供的 solution/answer 可能表现更好。我只是想尽可能避免指针。)

你可以试试:

vertex * current_buddy = NULL;

while(myQueue.empty() == false)
{
    vertex front_buddy = myQueue.front();
    cout << "THIS IS A FRIEND IN THE BREADTH-FIRST TRAVERSAL" << front_buddy.buddy_name << endl;
    current = front_buddy.head;

顺便说一句 - 我认为您需要在此处检查是否为空:

    while(current != NULL)
    {
        if (current->connected_buddy == NULL)
        {
            // add error handling
        }
        else
        {
            // normal code
        }
     }

这样你就不会再次崩溃

这部分

   while(current != NULL)
    {
        if(current->connected_buddy->visited == false)
        {
            // your code

            current = current->next;
        }

    }
如果 current->connected_buddy->visited 为真,

看起来像是一个无限循环。

也许你想要

   while(current != NULL)
    {
        if(current->connected_buddy->visited == false)
        {
            // your code

        }

        // Moved out of the if-statement
        current = current->next;
    }

这是段错误,因为您正试图引用 NULL 指针。

vertex * current_buddy = NULL;

while(myQueue.empty() == false)
{
    // V de-referencing a NULL pointer
    *current_buddy = myQueue.front();//THIS LINE SEG FAULTS

你应该把它改成

// vertex * current_buddy = NULL; // < Remove this line

while(myQueue.empty() == false)
{
    vertex *current_buddy = &myQueue.front();