EXC 对迭代器的错误访问
EXC Bad Access with Iterators
我创建了这个适用于向量、链表和双链表的函数。该函数获取一个值并在容器中搜索它。如果 vlaue 在容器中,则该函数会将值插入到已存在的位置旁边。因此,如果 val=2
那么 {3,2,5}
将变为 {3,2,2,5}
。但是如果容器中不存在该值,则将其添加到后面。
我使用迭代器编写了这个函数。它与向量一起工作得很好,但是当我尝试 运行 它与列表或双链表时,我在 if (*it==val)
行收到 Exc Bad Access 错误。我没有看到我做错了什么。
template <class Container, class T>
void insertNextTo( Container &x, const T &val){
typename Container::iterator it = x.begin();
while (it!=x.end() && *it!=val){
++it;
}
if (*it == val){
x.insert(it, val);
}
else{
x.push_back(val);
}
}
编辑:谢谢大家!您更改 if
语句的建议非常有效!
如果我错了有人纠正我,但我相信你的错误来自于这样一个事实,即当你的迭代器到达列表的末尾时,它实际上指向内存中列表最后一位之后的地址,它可能会或可能不会被初始化并且在范围内,这会导致您的程序出错。
如果该值尚不存在,当循环结束时it
将等于end()
,并且您不能解引用end()
。您需要将 if (*it == val)
改为 if (it != x.end())
:
//if (*it == val){
if (it != x.end()){
x.insert(it, val);
}
或者,因为你只插入一个值,如果你找到 val
那么你可以执行 insert()
并立即退出函数,然后 push_back()
只有当循环到达容器的末端:
template <class Container, class T>
void insertNextTo( Container &x, const T &val ) {
typename Container::iterator it = x.begin();
while (it != x.end()) {
if (*it == val) {
x.insert(it, val);
return;
}
++it;
}
x.push_back(val);
}
在这种情况下,您可以使用 std::find()
而不是手动循环来简化代码:
#include <algorithm>
template <class Container, class T>
void insertNextTo( Container &x, const T &val ) {
typename Container::iterator it = std::find(x.begin(), x.end(), val);
if (it != x.end()) {
x.insert(it, val);
} else {
x.push_back(val);
}
}
甚至这样,因为使用 end()
迭代器 insert()
是安全的,它实际上与 push_back()
:
相同
template <class Container, class T>
void insertNextTo( Container &x, const T &val ) {
typename Container::iterator it = std::find(x.begin(), x.end(), val);
x.insert(it, val);
}
改变
if (*it == val)
至:
if (it != x.end())
如果在容器中找不到 val
,则循环将在 it == x.end()
时结束。它指向数组末尾,因此间接通过它会导致未定义的行为。
我创建了这个适用于向量、链表和双链表的函数。该函数获取一个值并在容器中搜索它。如果 vlaue 在容器中,则该函数会将值插入到已存在的位置旁边。因此,如果 val=2
那么 {3,2,5}
将变为 {3,2,2,5}
。但是如果容器中不存在该值,则将其添加到后面。
我使用迭代器编写了这个函数。它与向量一起工作得很好,但是当我尝试 运行 它与列表或双链表时,我在 if (*it==val)
行收到 Exc Bad Access 错误。我没有看到我做错了什么。
template <class Container, class T>
void insertNextTo( Container &x, const T &val){
typename Container::iterator it = x.begin();
while (it!=x.end() && *it!=val){
++it;
}
if (*it == val){
x.insert(it, val);
}
else{
x.push_back(val);
}
}
编辑:谢谢大家!您更改 if
语句的建议非常有效!
如果我错了有人纠正我,但我相信你的错误来自于这样一个事实,即当你的迭代器到达列表的末尾时,它实际上指向内存中列表最后一位之后的地址,它可能会或可能不会被初始化并且在范围内,这会导致您的程序出错。
如果该值尚不存在,当循环结束时it
将等于end()
,并且您不能解引用end()
。您需要将 if (*it == val)
改为 if (it != x.end())
:
//if (*it == val){
if (it != x.end()){
x.insert(it, val);
}
或者,因为你只插入一个值,如果你找到 val
那么你可以执行 insert()
并立即退出函数,然后 push_back()
只有当循环到达容器的末端:
template <class Container, class T>
void insertNextTo( Container &x, const T &val ) {
typename Container::iterator it = x.begin();
while (it != x.end()) {
if (*it == val) {
x.insert(it, val);
return;
}
++it;
}
x.push_back(val);
}
在这种情况下,您可以使用 std::find()
而不是手动循环来简化代码:
#include <algorithm>
template <class Container, class T>
void insertNextTo( Container &x, const T &val ) {
typename Container::iterator it = std::find(x.begin(), x.end(), val);
if (it != x.end()) {
x.insert(it, val);
} else {
x.push_back(val);
}
}
甚至这样,因为使用 end()
迭代器 insert()
是安全的,它实际上与 push_back()
:
template <class Container, class T>
void insertNextTo( Container &x, const T &val ) {
typename Container::iterator it = std::find(x.begin(), x.end(), val);
x.insert(it, val);
}
改变
if (*it == val)
至:
if (it != x.end())
如果在容器中找不到 val
,则循环将在 it == x.end()
时结束。它指向数组末尾,因此间接通过它会导致未定义的行为。