类结束时的 boost::shared_ptr 错误

Posted

技术标签:

【中文标题】类结束时的 boost::shared_ptr 错误【英文标题】:boost::shared_ptr error at end of class 【发布时间】:2013-05-07 18:41:09 【问题描述】:
class SomeData;
typedef boost::shared_ptr<SomeData> data_ptr;

class ABC 
public:   ABC()

          ~ABC()cached_ptr.reset(); 

          data_ptr get_ptr() data_ptr x; return x; // it does work and returns a data_ptr

          bool someWork(data_ptr& passed_ptr) 
            if(cached_ptr == NULL) 
              cached_ptr = get_ptr();
              passed_ptr.reset(new SomeData(*cached_ptr));
            
            return true;
          

          data_ptr otherWork() 
            if(cached_ptr == NULL)  
                cached_ptr = get_ptr();
                data_ptr local_ptr = boost::make_shared<SomeData>(*cached_ptr);
            
            return data_ptr;   // after some more work
         

private:  data_ptr cached_ptr;   // class member
;

以上是我尝试开始工作的一些代码的简化。

确实如此,直到我添加了“cached_ptr”,它能够在连续调用之间缓存数据以避免每次调用 get_ptr()(它可能相当大)。

注意:我有 boost::make_shared 和 reset() - 我对两者都进行了试验,看看错误是否是由副本引起的。没有什么不同(正如预期的那样)。

我已经有 google 测试单元测试 - 当我添加 cached_ptr 时,google 测试一直给我“GTEST_HAS_SEH”类型的错误。

"unknown file: error: SEH exception with code 0xc000005 thrown in the test body."

析构函数出现错误:cached_ptr.reset();

Visual Studio 说:

    "First-chance exception at 0x00ceba41 in myFile_gtest.exe: 0xC0000005: 
Access violation reading location 0xfeeefeee."

没有它也会发生(最初我什至没有放置 reset(),我认为共享指针在超出范围时会自行杀死。

我的问题可能是什么?

提升 1.47

谢谢。

【问题讨论】:

您的函数void bool someWork(data_ptr&amp; passed_ptr) 应该返回一个bool,但不会返回任何内容。那是未定义的行为。你能发布真实的代码,或者一些足够接近的东西来进行有意义的分析吗? 还有,SomeData的定义是什么? 另一件事:问题可能出在您创建或使用ABC 的方式上。我想你应该准备一个SSCCE SomeData 是一个在依赖项目中定义的类 - 包含很多东西,其中一个 std::vector - 它是一种特殊的树。我不认为它是相关的......这应该适用于任何类型的课程? 好吧,如果您的SomeData 不遵守三规则,例如,复制构造它可能会导致诸如双重删除之类的麻烦。我还看到您通过原始指针持有子节点,这表明您正在使用 newdelete 进行一些手动内存管理,这很容易出错 【参考方案1】:
typedef boost::shared_ptr<SomeData> data_ptr;

data_ptr get_ptr()  data_ptr x; return x; 

  cached_ptr = get_ptr();
  passed_ptr.reset(new SomeData(*cached_ptr));

get_ptr() 返回了一个NULL 指针,然后你取消了它的引用。

您从未将 cached_ptr 设置为 NULL 以外的任何值,但这是一个单独的问题。

【讨论】:

对不起,我认为我的评论解释了 get_ptr() 做了很多工作,然后返回了该工作的结果。它不为空,并且代码在没有 cached_ptr 的情况下也能正常工作。 Andy Prowl 的 cmets 表明我没有复制构造函数——我使用的类没有,我想我可能不需要它。添加复制构造函数解决了这个问题。 @Thalia 啊,感谢您的澄清。我现在知道了。我以为您的意思是 work(动词),但实际上您的意思是 work(名词)。【参考方案2】:

您在以下片段中取消引用空指针 (*cached_ptr):

cached_ptr = get_ptr();
passed_ptr.reset(new SomeData(*cached_ptr));

所以你的程序变得不合时宜。在这种情况下,你不能做任何期望。

【讨论】:

对不起,我认为我的评论解释了 get_ptr() 做了很多工作,然后返回该工作的结果(作为“data_ptr”,在该函数中创建)。它不为空,并且代码在没有 cached_ptr 的情况下也能正常工作。 Andy Prowl 的 cmets 表明我没有复制构造函数——我使用的类没有,我想我可能不需要它。添加复制构造函数解决了这个问题。【参考方案3】:

正如 Andy Prowl 注意到的(在我的问题的 cmets 中),指针指向的类不包含复制构造函数。

boost::make_shared 需要一个复制构造函数才能进行复制...

在它不存在的情况下,它指向相同的数据,所以当原始指针超出范围时,缓存的指针失去了它的指向(尽管在调试时,它看起来仍然有它......)

SomeData 添加一个复制构造函数解决了这个问题。

【讨论】:

以上是关于类结束时的 boost::shared_ptr 错误的主要内容,如果未能解决你的问题,请参考以下文章

通过取消引用 boost::shared_ptr 找不到派生类的方法

boost shared_ptr 初始化为类成员

boost::shared_ptr

返回 boost::shared_ptr 和从返回的原始指针构造 boost::shared_ptr 有啥区别?

boost库之内存管理shared_ptr

Boost智能指针——shared_ptr