使用尾后迭代器 std::iter_swap 不好吗?
Is it bad to std::iter_swap with a past-the-end iterator?
我一直在使用 std::iter_swap
交换两个迭代器引用的元素。我一直在想,如果其中一个迭代器是尾后迭代器(类似的由 end()
返回),这会产生什么影响。
例如:
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
vector<int> is = { 1 };
cout << "Before: " << is.at(0) << endl;
iter_swap(is.begin(), is.end());
cout << "After: " << is.at(0) << endl;
return 0;
}
This code compiles and runs fine.
Before: 1
After: 0
很明显 1
已在某处交换,但这似乎有点奇怪。
1
现在在哪里?
0
是从哪里来的?它是 end()
迭代器的表示吗?我想它也可能是具有默认构造的 int
的默认值?
- 这是未定义的行为,还是通常以其他方式狡猾?我需要采取预防措施来防止这样做吗?
- 这个实现是特定的吗?这适用于所有迭代器还是仅适用于
vector
?
是的,这很糟糕。 iter_swat
需要取消引用两个迭代器,但您不能取消引用 end()
返回的迭代器。
从25.3.3 swap
(alg.swap)iter_swap
的效果是
Effects: swap(*a, *b).
Requires: a and b shall be dereferenceable. *a shall be swappable with (17.6.3.2) *b.
因为它取消引用了两个迭代器,如果其中一个迭代器超过了容器,您可能无法取消引用它。
Where is the 1 now?
可能超过了你的向量。它可能位于也可能位于 end_of_allocation.
内
Where has the 0 come from? Is it a representation of the end() iterator? I > guess it could also be the default value of an int that has default
constructed?
这是一个未初始化的值,可能是也可能不是 1。此外,您可能还会观察到内存访问错误/崩溃。
Is this undefined behaviour, or generally dodgy in some other way? Do I
need to take precautions to prevent against doing this?
是的,是的。切勿直接或间接访问分配块之外的内存。
Is this implementation specific? Does this apply for all iterators or
just for vector?
Not it is not implementation specific. It is undefined. It applies for all iterators.
我一直在使用 std::iter_swap
交换两个迭代器引用的元素。我一直在想,如果其中一个迭代器是尾后迭代器(类似的由 end()
返回),这会产生什么影响。
例如:
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
vector<int> is = { 1 };
cout << "Before: " << is.at(0) << endl;
iter_swap(is.begin(), is.end());
cout << "After: " << is.at(0) << endl;
return 0;
}
This code compiles and runs fine.
Before: 1
After: 0
很明显 1
已在某处交换,但这似乎有点奇怪。
1
现在在哪里?0
是从哪里来的?它是end()
迭代器的表示吗?我想它也可能是具有默认构造的int
的默认值?- 这是未定义的行为,还是通常以其他方式狡猾?我需要采取预防措施来防止这样做吗?
- 这个实现是特定的吗?这适用于所有迭代器还是仅适用于
vector
?
是的,这很糟糕。 iter_swat
需要取消引用两个迭代器,但您不能取消引用 end()
返回的迭代器。
从25.3.3 swap
(alg.swap)iter_swap
的效果是
Effects: swap(*a, *b).
Requires: a and b shall be dereferenceable. *a shall be swappable with (17.6.3.2) *b.
因为它取消引用了两个迭代器,如果其中一个迭代器超过了容器,您可能无法取消引用它。
Where is the 1 now?
可能超过了你的向量。它可能位于也可能位于 end_of_allocation.
内Where has the 0 come from? Is it a representation of the end() iterator? I > guess it could also be the default value of an int that has default constructed?
这是一个未初始化的值,可能是也可能不是 1。此外,您可能还会观察到内存访问错误/崩溃。
Is this undefined behaviour, or generally dodgy in some other way? Do I need to take precautions to prevent against doing this?
是的,是的。切勿直接或间接访问分配块之外的内存。
Is this implementation specific? Does this apply for all iterators or just for vector? Not it is not implementation specific. It is undefined. It applies for all iterators.