Jonathan Chiou
Jonathan Chiou

Reputation: 359

Linked list assignment operator

I wrote some code for the overloaded = operator for a linked list, but it's not doing anything for some reason and I can't figure out why.

the class containing the linked list is called String, with the struct ListNode being the nodes themselves.

ListNode:

struct ListNode
{
      char info;
      ListNode * next;
      ListNode(char newInfo, ListNode * newNext)
        : info( newInfo ), next( newNext )
      {
      }
};

String:

class String {

    private:
        ListNode* head;

    public:
    String( const char * s = "");
    String( const String & s );
    String operator = ( const String & s );
    ~String();
}
ostream & operator << ( ostream & out, String& str );
istream & operator >> ( istream & in, String & str );

String.cpp:

String::String( const char * s) {
    if (s == "") {
        head = NULL;
        return;
    }

    ListNode* newNode = new ListNode(s[0], NULL);
    head = newNode;
    ListNode* current = head;
    for (int i = 1; s[i] != 0; current = current->next) {
        current->next = new ListNode(s[i], NULL);
        ++i;
    }
}

String::String(const String& s ) {

    ListNode* current = new ListNode((s.head)->info, NULL); //make all next's null just in case
    head = current;
    for(ListNode* sstart = s.head->next; sstart != NULL; sstart = sstart->next) {
            current->next = new ListNode(sstart->info, NULL);
            current = current->next;
    }

}

//RETURN STRING BY REFERENCE OR COPY CONSTRUCTOR IS CALLED
String& String::operator = ( const String & s ) {
    ListNode* start = head;
    ListNode* tmp;
    while(start != NULL) {
        tmp = start->next;
        delete start;
        start = tmp;
    }

    head = NULL;

    if (s.head == NULL)
        return *this;    
    ListNode* current = new ListNode((s.head)->info, NULL); //make all next's null just in case
    head = current;
    for(ListNode* sstart = s.head->next; sstart != NULL; sstart = sstart->next) {
            current->next = new ListNode(sstart->info, NULL);
            current = current->next;
    }

    return *this;

}

String::~String() {
    ListNode* nextNode = head;
    ListNode* tmp;
    while(nextNode) {
        tmp = nextNode->next;
        delete nextNode;
        nextNode = tmp;
    }
}

ostream & operator << ( ostream & out, String& str) {

    for (int i = 0; i < str.length(); ++i) {
        out << str[i];
    }
    return out;

}

istream & operator >> ( istream & in, String & str ) {
    int len = in.gcount();
    char* buf = new char[len];
    char inChar;
    for(int i = 0; in >> inChar; ++i) {
        buf[i] = inChar;        
    }
    String tmp(buf);
    str = tmp;
}

In the first loop, I'm deleting the linked list pointed to by head. After that, I'm setting head to NULL for the case where s contains nothing at all. If it isn't, then, I set current to be a copy of the first ListNode in s and store current in head (if I traverse using head, then I lose the pointer to the start of the list). Finally, my 2nd loop will "attach" the rest of s to current.

When I run my code, nothing happens. my terminal will print out a blank line, and then nothing, suggesting to me that I'm probably going infinite somewhere. What is wrong with my code?

EDIT: changed deletion of linked list of this, issue still persists.

Upvotes: 3

Views: 5549

Answers (2)

michaeltang
michaeltang

Reputation: 2898

I test the code you put in the question , it seems it is the problem of overloading << hope it will help

ostream & operator << ( ostream & out, String& str) {

    ListNode *p = str.head; // change head to public or define a public function get_head;
    while(p)
    {
        out << p->info;
        p = p->next;
    }

    return out;

}

Upvotes: 1

jerry
jerry

Reputation: 2611

You are causing undefined behavior by accessing an object that has already been deleted (since tmp == start) in this code snippet:

tmp = start;
delete start;
start = tmp->next;

There may be other problems, but start by fixing that. For instance, you can store the next pointer in your temporary variable before deleting:

tmp = start->next;
delete start;
start = tmp;

Upvotes: 4

Related Questions