这是我对双链表的iterator
和const_iterator
的实现。程序具有强制性测试。当我运行程序时,我从测试中得到错误:
“减量运算符将迭代器向后移动,前缀”,原因是 致命错误情况:SIGSEGV-细分违规信号
我在做什么错?
test.cpp //这是我得到错误///
的测试文件TEST_CASE("Decrement operator moves the iterator backward", "[stage2]") {
list l;
append_to_list(l, { 5.55, 6.66, 7.77, 8.88 });
auto it = l.end();
SECTION("Prefix") {
REQUIRE(*(--it) == 8.88);
REQUIRE(*(--it) == 7.77);
REQUIRE(*(--it) == 6.66);
REQUIRE(*(--it) == 5.55);
REQUIRE(it == l.begin());
}
SECTION("Postfix") {
it--;
REQUIRE(*(it--) == 8.88);
REQUIRE(*(it--) == 7.77);
REQUIRE(*(it--) == 6.66);
REQUIRE(*it == 5.55);
REQUIRE(it == l.begin());
}
}
TEST_CASE("Decrement operator moves the (const) iterator backward", "[stage2]") {
list l;
append_to_list(l, { 5.55, 6.66, 7.77, 8.88 });
auto it = l.cend();
SECTION("Prefix") {
REQUIRE(*(--it) == 8.88);
REQUIRE(*(--it) == 7.77);
REQUIRE(*(--it) == 6.66);
REQUIRE(*(--it) == 5.55);
REQUIRE(it == l.cbegin());
}
SECTION("Postfix") {
it--;
REQUIRE(*(it--) == 8.88);
REQUIRE(*(it--) == 7.77);
REQUIRE(*(it--) == 6.66);
REQUIRE(*it == 5.55);
REQUIRE(it == l.cbegin());
}
}
list.hpp
class list {
private:
struct node {
double val = 0;
node* prev = nullptr;
node* next = nullptr;
};
node* head = nullptr;
node* tail = nullptr;
size_t num_elements = 0;
public:
class const_iterator {
node* current_ptr = nullptr;
const list* o_list = nullptr;
public:
using difference_type = std::ptrdiff_t;
using iterator_category = std::bidirectional_iterator_tag;
using value_type = const double;
using reference = const double&;
using pointer = const double*;
const_iterator() = default;
const_iterator(node* ptr, const list* gen);
const_iterator& operator++();
const_iterator operator++(int);
const_iterator& operator--();
const_iterator operator--(int);
reference operator*() const;
pointer operator->() const;
bool operator==(const const_iterator& rhs) const;
bool operator!=(const const_iterator& rhs) const;
friend class list;
};
class iterator {
node* current_ptr = nullptr;
const list* o_list = nullptr;
public:
using difference_type = std::ptrdiff_t;
using iterator_category = std::bidirectional_iterator_tag;
using value_type = double;
using reference = double&;
using pointer = double*;
iterator() = default;
iterator(node* ptr, const list* gen);
iterator& operator++();
iterator operator++(int);
iterator& operator--();
iterator operator--(int);
reference operator*() const;
pointer operator->() const;
operator const_iterator() const;
bool operator==(const iterator& rhs) const;
bool operator!=(const iterator& rhs) const;
friend class list;
};
list.cpp //我对迭代器和const_iterator的实现//
list::iterator list::begin() {
return list::iterator(head, this);
}
list::iterator list::end() {
return list::iterator(tail->next, this);
}
list::const_iterator list::begin() const {
return list::const_iterator(head, this);
}
list::const_iterator list::end() const {
return list::const_iterator(tail->next, this);
}
list::const_iterator list::cbegin() const {
return list::const_iterator(head, this);
}
list::const_iterator list::cend() const {
return list::const_iterator(tail->next, this);
}
list::iterator::iterator(node *ptr, const list *gen) {
this->current_ptr = ptr;
this->o_list = gen;
}
list::iterator& list::iterator::operator++() {
current_ptr = this->current_ptr->next;
return *this;
}
list::iterator& list::iterator::operator--() { //here triggers error!!!
current_ptr = this->current_ptr->prev;
return *this;
}
list::iterator list::iterator::operator++(int)
{
iterator old(*this);
++(*this);
return old;
}
list::iterator list::iterator::operator--(int)
{
iterator left(*this);
--(*this);
return left;
}
list::const_iterator& list::const_iterator::operator++() {
current_ptr = current_ptr->next;
return *this;
}
list::const_iterator& list::const_iterator::operator--() { //here triggers error!!!
current_ptr = current_ptr->prev;
return *this;
}
list::const_iterator list::const_iterator::operator++(int) {
const_iterator old = *this;
++(*this);
return old;
}
list::const_iterator list::const_iterator::operator--(int) {
const_iterator old = *(this);
--(*this);
return old;
}
答案 0 :(得分:1)
问题是您使用空node *
作为您的end(),它无法与operator--一起使用;没有办法减少它到达列表的最后一个节点。
您需要使用其他内容作为结束标记,以使您可以返回列表-列表中的假“节点”不是真实列表的元素,或者添加指向该列表的指针迭代器类的原始列表,因此当减少end()迭代器时,您可以恢复列表中的最后一个节点。
由于您的迭代器已经具有一个o_list
指针,因此最简单的方法就是使用它:
list::iterator& list::iterator::operator--() {
current_ptr = current_ptr ? current_ptr->prev : o_list->tail;
return *this;
}