重载迭代器 class 的前缀增量运算符抛出分段错误
Overloading prefix increment operator for iterator class throws segmentation fault
当迭代器到达链表 class 中的最后一个节点时,我遇到分段错误。
通过调试,我可以看到当迭代器到达链表的末尾时,node->next_
指向null,从而抛出段错误。
编辑:
我已经包含了 void push_front()
方法的定义
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;
}
}
我尝试将重载运算符更改为以下但没有成功:
iterator& operator++() {
iNode = iNode->next_; //this line throws the exception
return *this;
}
//and
iterator& operator++() {
return ++(*this);
}
非常感谢任何帮助!
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);
}
};
默认需要将head_
初始化为nullptr
:
Node* head_ = nullptr;
否则 head_
有一些不确定的值,push_front
中的以下检查不保证有效:
if (head_ == nullptr)
即使 head_
未指向有效内存。
请注意,即使您从未调用 push_front
,也会出现此问题,因为在 for
循环中检查 begin
迭代器的 iNode
可能不是 nullptr
,即使列表为空。这意味着 i
将递增,这导致访问 next_
.
时 operator++
中的 UB
这是 demo。 (如果你不初始化 head_
,程序会出现段错误。)
当迭代器到达链表 class 中的最后一个节点时,我遇到分段错误。
通过调试,我可以看到当迭代器到达链表的末尾时,node->next_
指向null,从而抛出段错误。
编辑:
我已经包含了 void push_front()
方法的定义
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;
}
}
我尝试将重载运算符更改为以下但没有成功:
iterator& operator++() {
iNode = iNode->next_; //this line throws the exception
return *this;
}
//and
iterator& operator++() {
return ++(*this);
}
非常感谢任何帮助!
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);
}
};
默认需要将head_
初始化为nullptr
:
Node* head_ = nullptr;
否则 head_
有一些不确定的值,push_front
中的以下检查不保证有效:
if (head_ == nullptr)
即使 head_
未指向有效内存。
请注意,即使您从未调用 push_front
,也会出现此问题,因为在 for
循环中检查 begin
迭代器的 iNode
可能不是 nullptr
,即使列表为空。这意味着 i
将递增,这导致访问 next_
.
operator++
中的 UB
这是 demo。 (如果你不初始化 head_
,程序会出现段错误。)