列表迭代器擦除“调试断言失败”

问题描述:

我有2个std ::列表。我想删除列表1中的所有项目并将其插入到第二个项目中,反之亦然。我的代码无法正常工作(获得访问冲突和“列表迭代器不dereferencable”)的第二个方法列表迭代器擦除“调试断言失败”

for (std::list<Item *>::iterator it = list1.begin(); it != list1.end(); ++it) { 
     it = list1.erase(it); 
     list2.push_back(*it); 
    } 
it = list1.begin(); 
it = list2.erase(it); // because the last element is not deleted in the above loop 
list2.push_back(*it); 

对称码。我设法在两个列表之间转移项目一次,但接下来我得到错误。

任何帮助?

+0

'std :: swap(list1,list2)'? – Johnsyweb 2013-02-10 23:33:43

+1

@Johnsyweb'std :: list :: swap'成员函数保证是恒定时间。它应该只涉及交换两个指针(可能是C++ 11中的一个大小数据成员)。 – juanchopanza 2013-02-10 23:40:08

+0

@juanchopanza:那肯定会更好。 std :: swap'函数仍然会执行比提供的实现更好:) – Johnsyweb 2013-02-10 23:43:39

这是很容易和有效地与std::listswap成员函数完成:

list1.swap(list2); 

这具有恒定时间复杂度。

+1

轻松获得最快,最好的答案。 – skypower 2013-02-10 23:42:33

+0

@skypower然后你可以用绿色的勾号来接受它。 – Csq 2013-02-10 23:48:38

当然,你必须使用list::swap。 但是你的代码显示你有一些误解。

for (std::list<Item *>::iterator it = list1.begin(); it != list1.end(); ++it) { 
    it = list1.erase(it); // this effectively erase and destroy *it, 
       // and erase() return an iterator to the NEXT element. 
       // Now it=it+1 
    list2.push_back(*it); // you copy the NEXT element!! 
    // here is where we efectively get the ++it of the 'for'. 
    // When erase was used when ‘it’ was at end()-1, erase return end() 
    // The attempt to do it=end()+1 is an error probably detected by an assertion. 
} 

如果list1有元素的最初偶数,例如0,1,2,3,4,5,6,7,8,9迭代end()将指向不存在10,你不要不需要(不能)清除。这'for'将删除偶数元素(0,2,4,6,8),并复制到list2奇数(1,3,5,7,9)。但如果最初list1有奇数元素,例如0,1,2,3,4,5,6,7,8最后删除的是8,erase返回一个迭代器到不存在的9 = end(),和'for'构成一个试图增加它,但不要通过断言。