Valgrind报告读取=带有嵌套shared_ptrs的运算符的错误

问题描述 投票:0回答:1

我有这个简单的代码

#include<memory>

class SLLNode{
        public:
                SLLNode(const int& d){
                        data_ = d;
                }
                std::shared_ptr<SLLNode> next_;
                int data_;
};

int main(){

        std::shared_ptr<SLLNode> head(new SLLNode(1));
        head->next_.reset(new SLLNode(2));
        *head = *(head->next_);
        return 0;
}

Valgrind在我的情况下抱怨读取无效。

==17312== Invalid read of size 4
==17312==    at 0x108EF3: SLLNode::operator=(SLLNode const&) (test_shared_ptr.cpp:3)
==17312==    by 0x108DA3: main (test_shared_ptr.cpp:16)
==17312==  Address 0x5b7dd50 is 16 bytes inside a block of size 24 free'd
==17312==    at 0x4C3123B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17312==    by 0x109511: std::_Sp_counted_ptr<SLLNode*, (__gnu_cxx::_Lock_policy)2>::_M_dispose() (shared_ptr_base.h:376)
==17312==    by 0x1090DF: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:154)
==17312==    by 0x109061: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::operator=(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) (shared_ptr_base.h:703)
==17312==    by 0x108E9A: std::__shared_ptr<SLLNode, (__gnu_cxx::_Lock_policy)2>::operator=(std::__shared_ptr<SLLNode, (__gnu_cxx::_Lock_policy)2> const&) (shared_ptr_base.h:1034)
==17312==    by 0x108EC4: std::shared_ptr<SLLNode>::operator=(std::shared_ptr<SLLNode> const&) (shared_ptr.h:93)
==17312==    by 0x108EEE: SLLNode::operator=(SLLNode const&) (test_shared_ptr.cpp:3)
==17312==    by 0x108DA3: main (test_shared_ptr.cpp:16)
==17312==  Block was alloc'd at
==17312==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17312==    by 0x108D5C: main (test_shared_ptr.cpp:15)

我使用的命令是:

valgrind --tool=memcheck ./test_shared_ptr

= operator似乎仅在使用嵌套shared_ptr时才引起此问题。我原本希望从ptr head中释放数据,并替换为ptr head.next_中的数据,但是由于我读取了无效的数据,因此似乎正在发生其他情况。我想替换head指向的数据(而不是head本身),因为此head ptr可能是head的另一个shared_ptr的副本。

c++ c++11 valgrind shared-ptr
1个回答
0
投票

隐式定义的赋值运算符如下所示:

SLLNode& SLLNode::operator=(const SLLNode& other) {
  next_ = other.next_;
  data_ = other.data_;
  return *this;
}

在您的示例中,otherSLLNode(2),并且仅通过head->next_中的引用将其保持活动状态。 other.next_NULL

上面的第一个分配将head->next_设置为NULL,这会导致SLLNode(2)被破坏,并给other留下一个悬空的参考。下一行在对象的生命周期结束后通过访问对象来显示未定义的行为。

© www.soinside.com 2019 - 2024. All rights reserved.