【问题标题】:Iterator: If '*' returns the reference of the element, why does delete *(myList.end()) gives SegFault迭代器:如果'*'返回元素的引用,为什么delete *(myList.end())会给出SegFault
【发布时间】:2018-05-06 21:12:35
【问题描述】:

对不起,如果这对您来说太基本了。但是,我想知道为什么从 std::list 中删除带有运算符 '*' 的方法返回的 'end()' 会给出分段故障。

[下面代码的注释:我有这个想法是因为this post]

请查看我的示例,以便您轻松理解我的意思。

#include <list>
#include <memory>

int main(int argc, char const *argv[])
{


    std::list<int*> myList;
    int *ptr1 = new int(1) , *ptr2 = new int(2);


    myList.push_back( ptr1 );
    myList.push_back( ptr2 );

    delete myList.back(); // !!<< this one is ok

    //delete *(myList.end());  // !!<< but, this gives segmentation fault
return 0;
}

【问题讨论】:

  • end() 返回一个在列表末尾之后的迭代器。它超出了范围,因此请自行承担取消引用它的风险。
  • 你的意思是什么时候结束,是不是因为列表是用哨兵实现的?
  • 好问题。没有好的答案。据我所知,它只有一个nullptr。这是end 上的可靠文档页面:en.cppreference.com/w/cpp/container/list/end。考虑将back() 用于您正在做的事情。

标签: c++ iterator segmentation-fault


【解决方案1】:

因为std::list::end() 返回一个迭代器,该迭代器指向最后一个元素之后的一个,取消引用它会调用 UB。而且因为那个地址不是new分配的,也不是nullptr(其实里面包含了无效数据),delete-ing是另一个UB。

delete *(myList.end())
//     ^ UB here

要访问第一个或最后一个元素(不是one-past-the-last !!),请使用front()back()

delete myList.front();
delete myList.back();
//     ^ No dereference here

参考:cppreference.com

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-19
    • 1970-01-01
    • 2016-09-23
    • 2019-05-29
    • 2020-04-05
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    相关资源
    最近更新 更多