简体   繁体   English

是否可以添加到 C++ 中空双端队列的迭代器?

[英]Should it be possible to add to an iterator of an empty deque in C++?

Here's an example of what will cause the problem:以下是导致问题的示例:

#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
}

Adding to an iterator of an empty deque only seems to be a problem if the deque has never contained any elements before.如果双端队列以前从未包含任何元素,则添加到空双端队列的迭代器似乎是一个问题。

I'm curious as to if this is a bug in the STL, or if I'm just using it in a way that causes undefined behavior.我很好奇这是否是 STL 中的错误,或者我只是以导致未定义行为的方式使用它。 I only get this problem when compiling with Xcode (both the GUI and the command line).我只在使用 Xcode(GUI 和命令行)编译时遇到这个问题。 I have also tried it with GCC version 6.2.0 on Linux, but the problem didn't seem to exist there.我也在 Linux 上使用 GCC 版本 6.2.0 进行了尝试,但问题似乎并不存在。

The issue you're running into here is that it's undefined behavior to use the + operator to jump an iterator forward beyond the spot one past the end of a container.您在这里遇到的问题是,使用+运算符将迭代器向前跳转到容器末尾的位置是未定义的行为 As a result, each of the iterator operations you're performing leads to undefined behavior, and it just so happens to be the case that the first two cases coincidentally don't crash while the last one does.结果,您正在执行的每个迭代器操作都会导致未定义的行为,而且恰好是前两种情况巧合地不会在最后一种情况下崩溃的情况。

(As for why this is undefined behavior: the C++17 standard requires that (§27.2.3/2), to increment an iterator, the iterator must be dereferencable , in the sense that it must safe and legal to dereference the iterator before you increment it. It then says (§27.2.7/1) that if you use + or += on an iterator, it should have the same effect as if you iteratively did ++ the appropriate number of times. As a result, if you jump an iterator more that one step past the end of a container, at some point you'll reach the end of the container where the iterator isn't dereferencable and will trigger undefined behavior.) (至于为什么这是未定义的行为:C++17 标准要求(第 27.2.3/2 节),要增加迭代器,迭代器必须是dereferencable ,因为在增加之前取消引用迭代器必须安全且合法然后它说(第 27.2.7/1 节)如果你在迭代器上使用++= ,它应该具有与迭代执行++适当次数相同的效果。因此,如果你将迭代器跳过超过容器末尾的一步,在某些时候您将到达容器的末尾,其中迭代器不可取消引用并会触发未定义的行为。)

Hope this helps!希望这可以帮助!

I'm curious as to if this is a bug in the STL, or if I'm just using it in a way that causes undefined behavior.我很好奇这是否是 STL 中的错误,或者我只是以导致未定义行为的方式使用它。 I only get this problem when compiling with Xcode (both the GUI and the command line).我只在使用 Xcode(GUI 和命令行)编译时遇到这个问题。

You are causing undefined behavior.您正在导致未定义的行为。

I have also tried it with GCC version 6.2.0 on Linux, but the problem didn't seem to exist there.我也在 Linux 上使用 GCC 版本 6.2.0 进行了尝试,但问题似乎并不存在。

No, the undefined behavior manifests itself differently there;不,未定义的行为在那里以不同的方式表现出来; it didn't cause a SEGFAULT the time you tried it.你尝试它的时候它并没有导致 SEGFAULT。 (It could next time you try it, though) (不过下次你可以试试)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM