【发布时间】:2020-06-24 00:23:24
【问题描述】:
以下是导致问题的示例:
#include <deque>
int main() {
std::deque<int> has_data = {1, 2, 3};
std::deque<int>::iterator iter1 = has_data.begin() + 5; // This works fine
std::deque<int> had_data = {4, 5, 6};
had_data.clear();
std::deque<int>::iterator iter2 = had_data.begin() + 5; // This also works fine
std::deque<int> is_empty;
std::deque<int>::iterator iter3 = is_empty.begin() + 5; // This causes a segfault
}
如果双端队列以前从未包含任何元素,添加到空双端队列的迭代器似乎是一个问题。
我很好奇这是否是 STL 中的错误,或者我只是以导致未定义行为的方式使用它。我只在使用 Xcode(GUI 和命令行)编译时遇到这个问题。我也试过在 Linux 上使用 GCC 6.2.0 版,但那里似乎不存在问题。
【问题讨论】:
-
对我来说听起来像是一个实现错误。另外,你为什么要增加迭代器过去
end?当deque只有 3 个元素(或 0 个元素)时使用+ 5无论如何都是错误的。 -
原因是(至少在我的程序中)用户可以输入无效的索引。当他们这样做时,它将检查以确保生成的迭代器在范围内,如果不在则显示错误消息。如果程序段错误,它就不能这样做。我目前的解决方法是在生成迭代器之前检查容器是否为空。虽然这工作正常,但我想检查它是否是一个实际的错误,或者只是我很愚蠢。如果是前者,我计划将其报告给适当的来源。
-
是什么阻止了您在将索引应用于迭代器之前对其进行验证?通过检查索引是否为
0 <= index < deque::size()很容易做到这一点。始终在使用之前验证/清理用户输入。 -
顺便说一句,在实际标准中没有提到标准模板库或STL,这个术语来自很久以前。如今它只是“标准”:-)
-
我真的不会那样写我的代码。我会对照
std::deque::size()检查输入的索引。
标签: c++ stl iterator c++17 stddeque