首页 > 解决方案 > 将指针分配给循环链表的头部时崩溃

问题描述

我正在做 Savitch 编写的使用 C++ 全球版解决问题的第 13 章的编程项目 6 。我试图重载<<运算符以打印列表。它一直工作到我的 walker 指针第二次分配给头指针的值,这使我无法将列表用作项目要求的循环链表。我在这里重新创建了崩溃源的最基本形式:

Suitors.h 文件:

#include <iostream>

struct Suitor {
    int number;
    Suitor *link;
};

class Suitors {
private:
    Suitor *head=nullptr;
    int size=0;
public:
    //Constructors
    Suitors(int sizePar);
    ~Suitors(); //Destructor

    //Print list
    friend std::ostream& operator<<(std::ostream& outs, const Suitors& list);
};

Suitors.cpp 文件:

#include "Suitors.h"

Suitors::Suitors(int sizePar) {
    Suitor *tempPtr = new Suitor;
    size = sizePar;
    for (int i=0; i<size; i++) {
        if (head==nullptr) {
            head = tempPtr;
        }
        tempPtr->number = i+1;
        if (i==size-1) {
            tempPtr->link = head;
        }
        else {
            tempPtr->link = new Suitor;
        }
        tempPtr = tempPtr->link;
    }
}

Suitors::~Suitors() {
    Suitor *walker1 = head, *walker2 = head;
    for (int i=0; i<size; i++) {
        walker1 = walker1->link;
        delete walker2;
        walker2 = walker1;
    }
    head = nullptr;
}

std::ostream& operator<<(std::ostream& outs, const Suitors& list) {
    Suitor *walker = list.head;
    walker = walker->link;
    walker = list.head;


    /*
    for (int i=0; i<list.size; i++) {
        outs << walker->number << " ";
        walker = walker->link;
    }
     */
}

main.cpp 文件:

#include <iostream>
#include "Suitors.h"

void project6();

int main() {
    std::cout << "Hello, World!" << std::endl;
    project6();
    return 0;
}

void project6() {
    Suitors six(6);
    std::cout << six << std::endl;
}

我已将 << 运算符重载缩减为造成错误的原因。walker 设置为链表头,然后推进一个节点,然后设置回链表头,导致错误。期望的行为是能够多次将 walker 设置为头节点。

标签: c++linked-listclioncircular-list

解决方案


当我编译你的代码时,编译器告诉了我两件事。

  1. 函数中没有return声明,std::ostream& operator<<(std::ostream&, const Suitors&)声明为返回非void
  2. outs函数的参数未使用。

尽管编译器缺乏人类智能,但他们确实擅长发现代码中的疏忽。return outs;因此,我通过在该函数中添加该行来解决这些警告。分段错误消失了。

始终启用并解决编译器警告!


推荐阅读