c – unique_ptr:链表项删除

前端之家收集整理的这篇文章主要介绍了c – unique_ptr:链表项删除前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我目前正在考虑在unique_ptrs的帮助下实现单个链表.尽管由于析构函数的递归调用可能导致堆栈溢出(参见 Stack overflow with unique_ptr linked list),但我遇到了以下问题:
假设,我们有链接列表的以下实现
struct node {
  node (void) : val(0),next(nullptr) {}
  int val;
  std::unique_ptr<node> next;
};

我们已按照初步确定了我们的清单

int main (int argc,char* argv[]) {
  node HEAD;
  HEAD.val = 0;
  auto ptr = &HEAD;
  for (int i = 0; i < 10; ++i) {
    ptr->val = i;
    ptr->next.reset(new node);
    ptr = ptr->next.get();
  }
  ptr->val = 10;
  ...

现在,我想删除值为1的节点:

ptr = &HEAD;
ptr = ptr->next.get();
HEAD.next = std::move(ptr->next);

乍一看,这似乎是明智的.不过,我不确定它是否会导致未定义的行为:

根据http://en.cppreference.com/w/cpp/memory/unique_ptr/operator%3D,
运算符=

Transfers ownership from r to *this as if by calling reset(r.release())
followed by an assignment of get_deleter() from std::forward
(r.get_deleter())

仔细看看unique_ptr :: reset(http://en.cppreference.com/w/cpp/memory/unique_ptr/reset),它会读取

Given current_ptr,the pointer that was managed by *this,performs the
following actions,in this order:

  1. Saves a copy of the current pointer old_ptr = current_ptr

  2. Overwrites the current pointer with the argument current_ptr = ptr

  3. If the old pointer was non-empty,deletes the prevIoUsly managed object
    if(old_ptr != nullptr) get_deleter()(old_ptr)

这意味着在这种情况下,r.get_deleter()的调用将引用一个已被销毁的对象,或者我在这里弄错了?

非常感谢您的回复.

解决方法

你的担忧似乎对我有用. ptr-> next.get_deleter()不再存在,因为当ptr复位时,ptr-> next被破坏(虽然不再拥有任何东西)和* ptr.在大多数情况下,它可能不重要,因为删除器将是一个空基类,并且赋值将是一个无操作,但仍然是技术上未定义的行为.

我会选择HEAD.next.reset(ptr-> next.release());显式(如果你不关心删除),或HEAD.next = std :: unique_ptr< node>(std :: move(ptr-> next))如果你担心保留删除器.

猜你在找的C&C++相关文章