标签: shared-ptr

从shared_ptr中分离指针?

可能重复:
如何从boost :: shared_ptr释放指针?

我的接口函数返回一个指向对象的指针.用户应该拥有该对象的所有权.我不想返回Boost.shared_ptr,因为我不想强制客户端使用boost.但是,在内部,我想将指针存储在shared_ptr中,以防止在异常等情况下发生内存泄漏.似乎无法从共享指针中分离指针.这里有什么想法?

c++ boost shared-ptr

28
推荐指数
4
解决办法
3万
查看次数

Equality-compare std :: weak_ptr

我想比较两个std :: weak_ptr或一个std :: weak_ptr和一个std :: shared_ptr的相等性.

我想知道的是weak_ptr/shared_ptr指向的每个对象是否相同.比较应该产生负面结果,不仅如果地址不匹配,而且如果基础对象被删除然后偶然使用相同地址重建.

所以基本上,即使分配器保留相同的地址,我也希望这个断言成立:

auto s1 = std::make_shared<int>(43);
std::weak_ptr<int> w1(s1);

s1.reset();

auto s2 = std::make_shared<int>(41);
std::weak_ptr<int> w2(s2);

assert(!equals(w1,w2));
Run Code Online (Sandbox Code Playgroud)

weak_ptr模板不提供相等的运算符,正如我所理解的那样,这是有充分理由的.

所以一个天真的实现看起来像这样:

template <typename T, typename U>
inline bool naive_equals(const std::weak_ptr<T>& t, const std::weak_ptr<U>& u)
{
    return !t.expired() && t.lock() == u.lock();
}

template <typename T, typename U>
inline bool naive_equals(const std::weak_ptr<T>& t, const std::shared_ptr<U>& u)
{
    return !t.expired() && t.lock() == u;
}
Run Code Online (Sandbox Code Playgroud)

如果第一个weak_ptr在此期间到期,则它会产生0.如果不是,我将weak_ptr升级为shared_ptr并比较地址.

这个问题是我必须锁定weak_ptr两次(一次)!我担心花费太多时间.

我想出了这个:

template <typename T, typename U>
inline bool equals(const …
Run Code Online (Sandbox Code Playgroud)

c++ shared-ptr weak-ptr c++11

28
推荐指数
1
解决办法
1万
查看次数

使用std :: move与std :: shared_ptr

我有一个定义如下的函数:

void foo(std::shared_ptr<X> x) { ... };
Run Code Online (Sandbox Code Playgroud)

如果我将共享ptr声明为X:

std::shared_ptr<X> sourcePtr(new X(...));
Run Code Online (Sandbox Code Playgroud)

然后我可以打电话foo如下:

foo(std::move(sourcePtr));
Run Code Online (Sandbox Code Playgroud)

要么

foo(sourcePtr);
Run Code Online (Sandbox Code Playgroud)

我明白,如果我使用第一个选项,则sourcePtr变为null.它是否也会阻止引用计数递增?

如果这无关紧要,我更喜欢哪个选项?做出这样的决定时,我应该考虑其他事情吗?

c++ shared-ptr move-semantics c++11

28
推荐指数
1
解决办法
2万
查看次数

enable_shared_from_this和继承

我有一个继承自的类型enable_shared_from_this<type>,以及从这种类型继承的另一种类型.现在我不能使用shared_from_this方法,因为它返回基类型,并且在特定的派生类方法中我需要派生类型.从这个直接构造shared_ptr是否有效?

编辑:在一个相关的问题中,我如何从一个类型的左值移动shared_ptr<base>到一个类型shared_ptr<derived>?我使用dynamic_cast来验证它确实是正确的类型,但现在我似乎无法完成实际的移动.

c++ boost smart-pointers shared-ptr c++11

27
推荐指数
1
解决办法
6204
查看次数

提升Shared_pointer NULL

reset()用作shared_pointer的默认值(相当于a NULL).

但是如何检查shared_pointer是否是NULL

这会返回正确的价值吗?

boost::shared_ptr<Blah> blah;
blah.reset()
if (blah == NULL) 
{
    //Does this check if the object was reset() ?
}
Run Code Online (Sandbox Code Playgroud)

c++ boost smart-pointers shared-ptr

27
推荐指数
4
解决办法
3万
查看次数

boost的shared_ptr(shared_ptr <Y> const&r,T*p)用于什么?

boost::shared_ptr 有一个不寻常的构造函数

template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p);
Run Code Online (Sandbox Code Playgroud)

我对这对什么有用感到有些疑惑.基本上它与股份共享r,但.get()将返回p. r.get()!

这意味着您可以执行以下操作:

int main() {
    boost::shared_ptr<int> x(new int);
    boost::shared_ptr<int> y(x, new int);

    std::cout << x.get() << std::endl;
    std::cout << y.get() << std::endl;

    std::cout << x.use_count() << std::endl;
    std::cout << y.use_count() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

你会得到这个:

0x8c66008
0x8c66030
2
2
Run Code Online (Sandbox Code Playgroud)

请注意,指针是分开的,但它们都声称具有use_count2(因为它们共享同一对象的所有权).

因此,所int拥有的x将存在只要x 即将存在y.如果我理解文档是正确的,那么第二个int永远不会被破坏.我通过以下测试程序证实了这一点:

struct T {
    T() { std::cout << …
Run Code Online (Sandbox Code Playgroud)

c++ boost smart-pointers shared-ptr

26
推荐指数
2
解决办法
2423
查看次数

你可以将shared_ptr用于C风格数组的RAII吗?

我正在研究一段代码,它有许多可能的故障点,导致它提前退出函数.我正在与之交互的库要求将C样式的数组传递给函数.所以,我没有在每个出口点调用数组上的delete,而是这样做:

void SomeFunction(int arrayLength)
{
   shared_ptr<char> raiiArray(new char[arrayLength]);
   pArray = raiiArray.get();

   if(SomeFunctionThatRequiresCArray(pArray) == FAILED) { return; }

   //etc.
}
Run Code Online (Sandbox Code Playgroud)

我想使用unique_ptr,但我当前的编译器不支持它,并且引用计数开销在这种情况下并不重要.

我只是想知道在与遗留代码接口时是否有人对这种做法有任何想法.

更新 我完全忘了shared_ptr呼叫delete而不是delete [].我刚看到没有内存泄漏,并决定采用它.甚至没想过用矢量.因为我最近一直在钻研新的(对我来说)C++我认为我有一个案例"如果你拥有的唯一工具是锤子,那么一切看起来都像钉子一样." 综合征.感谢您的反馈.

UPDATE2我想我会改变这个问题并提供一个答案,让那些犯了同样错误的人更有价值.虽然有类似的替代方案scoped_array,shared_array并且vector,您可以使用a shared_ptr来管理数组的范围(但在此之后我不知道为什么我会想要):

template <typename T>
    class ArrayDeleter
    {
    public:
        void operator () (T* d) const
        {
            delete [] d;
        }
    };

void SomeFunction(int arrayLength)
    {
       shared_ptr<char> raiiArray(new char[arrayLength], ArrayDeleter<char>());
       pArray = raiiArray.get();

       if(SomeFunctionThatRequiresCArray(pArray) == FAILED) { return; }

       //etc. …
Run Code Online (Sandbox Code Playgroud)

c++ raii shared-ptr

26
推荐指数
5
解决办法
2万
查看次数

为什么make_shared的大小有两个指针?

如该代码所示这里,从make_shared返回的对象的大小是两个指针.

但是,为什么不能make_shared像下面这样工作(假设T是我们正在制作共享指针的类型):

结果make_shared一个指针大小,它指向已分配的大小内存sizeof(int) + sizeof(T),其中int是引用计数,并且这在指针的构造/销毁时递增和递减.

unique_ptrs只是一个指针的大小,所以我不确定为什么共享指针需要两个.据我所知,它需要一个引用计数,它make_shared可以与对象本身一起放置.

此外,是否有任何实现以我建议的方式实现(不必intrusive_ptr为特定对象使用s)?如果没有,我建议实施的原因是什么原因可以避免?

c++ shared-ptr c++11

26
推荐指数
1
解决办法
1万
查看次数

在std :: shared_ptr上使用.reset()会删除所有实例

我是shared_ptr的新手,我正试图弄清楚.reset()函数的确切功能.

#include <memory>
#include <stdio>

using namespace std;
class SomeClass{};

int main() 
{
   shared_ptr<SomeClass> sp (nullptr);

   //do some stuff, sp now has 10 co-owners

   cout << sp.use_count << endl;
   sp.reset();
   cout << sp.use_count << endl;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

会输出

10
0
Run Code Online (Sandbox Code Playgroud)

因为我使用了reset函数是从内存中删除了所有实例吗?因为,我刚刚用sp消除了任何可能的内存泄漏?显然,这是一个我快速编写的玩具示例,对不起,如果有任何错误.

跟进情况:

shared_ptr<SomeClass> returnThis() {
    shared_ptr<SomeClass> someObject(new SomeClass(/*default constructor for example*/) );
    return someObject;
}
Run Code Online (Sandbox Code Playgroud)

在主要的地方:

shared_ptr<SomeClass> mainObject;
mainObject = returnThis();
Run Code Online (Sandbox Code Playgroud)

mainObject的使用次数是否为2,因为someObject是在函数中创建但从未清除过的?或者它是一个,并在返回值时自动完成清理?

c++ memory memory-leaks shared-memory shared-ptr

26
推荐指数
2
解决办法
3万
查看次数

为什么libc ++的shared_ptr实现使用全内存屏障而不是放松?

在boost的实现中shared_ptr,它使用宽松的内存排序来增加其引用计数.这似乎是安全的,因为减量使用获取/释放来确保在释放内存之前线程可以看到任何先前的减量.这种方法似乎是正确的,并出现在Herb Sutters 谈论原子论

在libc ++中,实现使用全内存屏障

template <class T>
inline T
increment(T& t) _NOEXCEPT
{
    return __sync_add_and_fetch(&t, 1);
}

template <class T>
inline T
decrement(T& t) _NOEXCEPT
{
    return __sync_add_and_fetch(&t, -1);
}

}  // name
Run Code Online (Sandbox Code Playgroud)

这个决定有理由吗?它们之间是否有任何性能或安全差异?

c++ boost thread-safety shared-ptr libc++

26
推荐指数
1
解决办法
1299
查看次数