首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用std::list: remove使用容器中的元素的别名删除元素正确吗?

用std::list: remove使用容器中的元素的别名删除元素正确吗?
EN

Stack Overflow用户
提问于 2019-09-20 17:50:33
回答 1查看 94关注 0票数 8

当我编译这个程序时:

代码语言:javascript
复制
#include <list>

int main() {
    std::list<int> l = {1, 2};
    l.remove(l.front());
}

使用clang使用ASAN和debug:

代码语言:javascript
复制
clang++-8 -fno-omit-frame-pointer -g -fsanitize=address -D_GLIBCXX_DEBUG -std=c++11 list-remove.cpp

我得到了一个heap-use-after-free

代码语言:javascript
复制
==31868==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000000020 at pc 0x0000004fa1ae bp 0x7fff52cc5630 sp 0x7fff52cc5628
READ of size 4 at 0x603000000020 thread T0
    #0 0x4fa1ad in std::__debug::list<int, std::allocator<int> >::remove(int const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/debug/list:649:18
    #1 0x4f990f in main /tmp/list-remove.cpp:5:7
    #2 0x7ff27d974b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #3 0x41b879 in _start (/tmp/list-remove+0x41b879)

remove找到与第一个元素匹配的x时,它似乎会从列表中删除该元素并删除它。当它检查第二个元素时,它使用已经被删除的x来比较该元素。

按照C++标准,这是一个正确的实现吗?似乎最好先将元素移到末尾,然后删除它们。这将避免heap-use-after-free错误,但可能不需要这样的实现。

优先选择中,它没有提到value不能是容器中元素的别名。

下面是我使用的c++版本:

代码语言:javascript
复制
$ /usr/bin/c++ --version
c++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-20 19:38:56

这个问题在LWG 526中被问到(并得到了回答),它说:

list::remove(value)之所以需要工作,是因为标准没有授权它不能工作。

这是在libc++ 回到2014年中修复的

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58033075

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档