0

I am doing programming project 6 of chapter 13 of Problem Solving With C++ Global Edition by Savitch. I am trying to overload the << operator to print the list. It works up to the point where my walker pointer is assigned to the value of the head pointer for the 2nd time, making it impossible for me to use the list as a circularly linked list which is the project requirement. I've recreated the most basic form of the source of the crash here:

Suitors.h file:

#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 File:

#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 file:

#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;
}

I've trimmed down the << operator overloading to just what creates the error. walker is set to the list head, then advanced a node, then set back to the list head, causing the error. The desired behavior is to be able to set walker to the head node more than once.

Weekooky
  • 1
  • 1
  • From the information you have given, it is impossible to say. The symptom may happen to occur at the point you describe, but the cause will be in code you haven't shown that was executed before that (e.g. that intialised or changes values the `Suitors` object that the caller passes, or any of the objects it links to). There are numerous ways that can happen in a way that causes bad pointers which, if accessed or modified, will cause undefined behaviour. Read up on how to provide a [mcve] - a minimal but complete sample of code that *someone else* can use to recreate the symptom you describe. – Peter Feb 04 '21 at 00:23
  • 1
    You don't want to do `walker = walker->link;` until you are absolutely certain that `walker`'s not null. – user4581301 Feb 04 '21 at 01:06
  • 1
    Just because this is where the program crashes or reports an error doesn't mean that's where the problem is. C++ does not work this way. The problem can be anywhere in your code, but after the bug occurs the program keeps running for a little bit before it finally crashes here. This is why stackoverflow.com's [help] requires you to show a [mre] that anyone can cut/paste ***exactly as shown***, then compile, run, and reproduce your problem. See [ask] for more information. Until you do that, it is unlikely that anyone will be able to figure out your problem. – Sam Varshavchik Feb 04 '21 at 01:26
  • That is much better. For your next step, see [Why should I always enable compiler warnings?](https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings) You don't need us to tell you what is wrong; your compiler is very willing to tell you if you just ask it to (with `-Wall`). – JaMiT Feb 05 '21 at 05:25

1 Answers1

0

When I compiled your code, the compiler told me two things.

  1. There is no return statement in the function std::ostream& operator<<(std::ostream&, const Suitors&), which is declared as returning non-void.
  2. The outs parameter to that function is unused.

Even though compilers lack human intelligence, they sure are good at spotting oversights in code. So I addressed those warnings by adding the line return outs; to that function. The segmentation fault went away.

Always enable and address compiler warnings!

JaMiT
  • 14,422
  • 4
  • 15
  • 31