简体   繁体   中英

Overloading prefix increment operator for iterator class throws segmentation fault

I'm getting segmentation faults when the iterator reaches the last node in class the linked list. By debugging, I can see that when the iterator reaches the end of the linked list, node->next_ points to null and thus throws the seg fault.

EDIT:

I've include the definition for void push_front() method

List.h

    void push_front(const T& value) {
        
        Node* node = new Node(value, nullptr, nullptr);

        if (head_ == nullptr) {
            head_ = node;
            tail_ = head_;
        }
        else {
            node->next_ = head_;
            head_ = node;
        }
    }

I tried to change the overloaded operator to the follow with no luck:

iterator& operator++() {
    iNode = iNode->next_;  //this line throws the exception
    return *this;
}

//and

iterator& operator++() {
    return ++(*this);
}

Any help is greatly appreciated!

main.cpp

#include <iostream>
#include "List.h"
#include <string>

int main(){

    List<int> l1;

    l1.push_front(4);
    l1.push_front(3);
    l1.push_front(2);
    l1.push_front(1);
    l1.push_front(0);


    for (auto i = l1.begin(); i != l1.end(); ++i)
    {
        int j = 0;  
    }

    l1.printList();
}



List.h

template<typename T>
class List
{
public:

    class Node {
    public:

        Node(T value, Node* prev, Node* next) : value_(value), prev_(prev), next_(next) {}

        T value_;
        Node* next_;
        Node* prev_;
    };

    Node* head_;
    Node* tail_;

    //! An iterator over the list
    class iterator
    {
    public:

        Node* iNode;
        iterator(Node* head): iNode(head){ }
        ~iterator() {}

        T& operator*() {
            return  iNode -> value_;
        }
    
        //prefix increment
        iterator& operator++() {
            this->iNode = this->iNode->next_;  //this line throws the exception
            return *this;

        }
           
        //postfix increment
        iterator operator++(int ignored) {
            iterator result = *this; 
            ++(*this); 
            return result;
        }

        bool operator== (const iterator& it) const {
            return iNode == it.iNode;
        }

        bool operator!= (const iterator& it) const {
            return !(iNode == it.iNode);
        }
     };

//! Get an iterator to the beginning of the list
    iterator begin() {
        return List<T>::iterator(head_);
    }

    //! Get an iterator just past the end of the list
    iterator end() {
        return List<T>::iterator(nullptr);
    }
};

You need to initialize head_ to nullptr by default:

Node* head_ = nullptr;

otherwise head_ has some indeterminate value, and the following check in push_front is not guaranteed to work:

if (head_ == nullptr)

even though head_ is not pointing to valid memory.

Note that this problem arises even if you never call push_front , because in the for loop check the begin iterator's iNode may not be nullptr , even if the List is empty. This means i will be incremented, which causes UB in the operator++ when accessing next_ .

Here's a demo . (If you don't initialize head_ , the program segfaults.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM