【问题标题】:Why is the end() element in Associative container print the same value as the last element? [duplicate]为什么关联容器中的 end() 元素打印的值与最后一个元素相同? [复制]
【发布时间】:2020-12-10 13:51:23
【问题描述】:

在下面的代码中,迭代器指向的值对于最后一个和倒数第二个元素都是相同的。

#include <iostream>
#include <set>
using namespace std;


int main() 
{
    set<int> s1 = {4,3,2,5,1};
    set<int>::iterator i;
    
    i = s1.end();
    cout << *i << endl; // 5
    
    i--;
    cout << *i << endl; // 5
    
    
    cout << *s1.end() << endl;  // 5
    cout << *(--s1.end()) << endl;  // 5
    
    return 0;
}

在我的理解中,end 元素指向的值应该是 null。 为什么会这样?

【问题讨论】:

  • “在我的理解中,end 元素指向的值应该是 null” - 即使这是真的(事实并非如此),取消引用空指针会调用 未定义的行为
  • 目标是vector,但其实是一样的,关联容器没什么特别的。

标签: c++ c++11 containers


【解决方案1】:

你调用了未定义的行为,std::set::end

返回一个迭代器到最后一个元素之后的元素 放。 该元素充当占位符;试图访问它会导致 未定义的行为。


Undefined behavior 使整个程序毫无意义。

【讨论】:

    【解决方案2】:

    在我的理解中,end 元素指向的值应该是 null。为什么会这样?

    为什么你的理解是错误的,我不知道;)。除了刻薄之外:不。没有“结束元素”。 end 迭代器指向最后一个元素之后的位置。你不能取消引用它。如果你这样做,你会调用未定义的行为。

    容器中的最后一个元素通常称为“后退”,许多容器都有一个back() 方法来访问它。

    【讨论】:

      【解决方案3】:

      在我的理解中,end 元素指向的值应该为 null。为什么会这样?

      不是。

      one-past-the-end 迭代器并不“指向”任何东西;它是不可取消引用的。

      C-strings 一开始可能看起来是这个规则的一个例外,但它们不是:它们在逻辑上由一个您可以检查的 NULL 字符终止,但 NULL 仍然是char 对象的数组,并且您不能取消引用 char* 这是该数组的最后一次迭代器。将 C 字符串的空终止符视为“此页面故意留空”;该页面不再为您提供任何故事,但它仍然是一个页面。

      为什么关联容器中的 end() 元素打印的值与最后一个元素相同?

      这是程序未定义行为的一种可能结果。

      【讨论】:

        猜你喜欢
        • 2020-07-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多