标签: smart-pointers

如何使用shared_ptr避免内存泄漏?

请考虑以下代码.

using boost::shared_ptr;
struct B;
struct A{
    ~A() { std::cout << "~A" << std::endl; }
    shared_ptr<B> b;    
};
struct B {
    ~B() { std::cout << "~B" << std::endl; }
    shared_ptr<A> a;
};

int main() {
    shared_ptr<A> a (new A);
    shared_ptr<B> b (new B);
    a->b = b;
    b->a = a;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

没有输出.没有调用desctructor.内存泄漏.我一直认为智能指针有助于避免内存泄漏.

如果我需要在类中进行交叉引用,我该怎么办?

c++ boost memory-leaks smart-pointers shared-ptr

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

共享的指针传染媒介,在清除传染媒介以后的记忆问题

我意识到在调用vector.clear()哪个持有共享指针之后,shared_ptr没有释放拥有的对象的析构函数.

代码示例如下所示.即使vector.clear()被调用,在共享指针之后调用的析构函数超出了范围.我的问题是 - 我是否必须通过重置它们来手动删除向量内的所有智能指针?有没有更简单的方法可以提供建议?

Output :   

constructor
I am here
destructor

Code:

#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class A
{
public:
    A(){cout << "constructor" << endl;};
    ~A(){cout << "destructor"  << endl;};
};

int main( )
{
    shared_ptr<A> sharedptr (new A);
    std::vector<shared_ptr<A> > test;
    test.push_back(sharedptr);

    test.clear();
    cout << "I am here" << endl;
}
Run Code Online (Sandbox Code Playgroud)

c++ memory smart-pointers vector

23
推荐指数
2
解决办法
4万
查看次数

C++使用Smart Pointers来改变指针值

考虑一个C库,它定义了用于创建,销毁和使用自定义结构的函数

struct Foo;
void foo_action(Foo*);
Foo* foo_create();
void foo_free(Foo*);
Run Code Online (Sandbox Code Playgroud)

目前,我在我的C++项目中使用了库,如下所示

Foo* myfoo = foo_create();
foo_action(myfoo);
foo_free(myfoo);
Run Code Online (Sandbox Code Playgroud)

我理解为什么智能指针很重要并希望迁移我的代码以使用它们.这就是代码现在的样子.

#include <memory>
#include <functional>
typedef std::unique_ptr<Foo, std::function<void(Foo*)>> FooPtr;
// ...
FooPtr myfoo2(foo_create(), foo_free);
foo_action(myfoo2.get());
Run Code Online (Sandbox Code Playgroud)

它似乎工作,但myfoo2.get()调用看起来很hacky.我按预期使用它吗?

该库的另一部分创建并使用某种列表结构.api看起来像

struct Bar;
Bar* bar_append(Bar*, int);
void bar_free_recursive(Bar*);
Run Code Online (Sandbox Code Playgroud)

并用作

// using NULL as current Bar* creates the initial structure
Bar* bar = bar_append(NULL, 1);
// each invocation leads to another 'head' structure
bar = bar_append(bar, 42);
bar = bar_append(bar, 123);
Run Code Online (Sandbox Code Playgroud)

当指针(指向的地址)随每次bar_append调用而改变时,我如何在这里引入智能指针,以便bar_free_recursive在释放指针实例时在当前指针值上调用?

c++ smart-pointers

23
推荐指数
2
解决办法
2425
查看次数

将std :: unique_ptr推回std :: vector时,编译器不会失败

一个unique_ptr不能被推回到一个std::vector,因为它是不可复制的,除非std::move被使用。但是,让我们F使用一个返回a的函数unique_ptr,然后std::vector::push_back(F())允许该操作。下面是一个示例:

#include <iostream>
#include <vector>
#include <memory>

class A {
  public:
    int f() { return _f + 10; }

  private:
    int _f = 20;
};

std::unique_ptr<A> create() { return std::unique_ptr<A>(new A); }


int main() {
  std::unique_ptr<A> p1(new A());

  std::vector< std::unique_ptr<A> > v;

  v.push_back(p1); // (1) This fails, should use std::move

  v.push_back(create()); // (2) This doesn't fail, should use std::move?

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

(2)允许,但(1)不允许。这是因为返回的值被隐式地移动了吗?

在中(2) …

c++ smart-pointers stdvector move-semantics

22
推荐指数
3
解决办法
1822
查看次数

智能指针的优点和缺点

我开始知道智能指针用于资源管理并支持RAII.

但是智能指针看起来不聪明并且使用它时需要注意的事项是什么?

c++ smart-pointers

21
推荐指数
4
解决办法
9781
查看次数

如何使用unique_ptr执行dynamic_cast?

我有一个类层次结构如下:

class BaseSession : public boost::enable_shared_from_this<BaseSession>
class DerivedSessionA : public BaseSession
class DerivedSessionB : public BaseSession
Run Code Online (Sandbox Code Playgroud)

在派生类函数中,我经常调用这样的函数:

Func(boost::dynamic_pointer_cast<DerivedSessionA>(shared_from_this()));
Run Code Online (Sandbox Code Playgroud)

由于我正在与shared_ptr管理会议,这工作正常.最近,我发现我shared_ptr对这种情况的使用不是最佳的.这是因为这些会话是单个对象,每个客户端维护一个套接字.如果重新连接套接字,则会话副本将成为僵尸.

作为解决方法,我开始通过shared_ptr引用传递而不是复制.这解决了僵尸问题.

理想情况下,我觉得我应该unique_ptr用来存储会话,然后将引用传递给其他函数.这打开了一大堆蠕虫.

如何将基类unique_ptr对象转换为派生类unique_ptr对象?unique_ptr以下行的版本是什么?

Func(boost::dynamic_pointer_cast<DerivedSessionA>(shared_from_this()));
Run Code Online (Sandbox Code Playgroud)

我只想要一个会话对象的副本,其他一切都应该是参考.

c++ boost dynamic-cast smart-pointers unique-ptr

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

我应该使用std :: shared指针传递指针吗?

假设我有一个由a管理的对象std::unique_ptr.我的代码的其他部分需要访问此对象.传递指针的正确解决方案是什么?我应该只是通过普通指针,std::unique_ptr::get还是应该使用并传递一个std::shared_ptr而不是std::unique_ptr根本?

我有一些偏好,std::unique_ptr因为该指针的所有者实际负责清理.如果我使用共享指针,那么由于共享指针,对象将有可能保持活动状态,即使它实际上应该被销毁.

编辑:不幸的是,我忘了提到指针不仅仅是函数调用的参数,而是存储在其他对象中以构建对象的网络结构.我不喜欢共享指针,因为它不再清楚,谁拥有该对象.

c++ pointers smart-pointers c++11

21
推荐指数
2
解决办法
3049
查看次数

std :: shared_ptr和std :: experimental :: atomic_shared_ptr有什么区别?

我阅读以下通过文章安东尼威廉姆斯和我除了理解为原子共享计数std::shared_ptrstd::experimental::atomic_shared_ptr实际指针到共享对象也是原子?

但是,当我读到的引用计数的版本lock_free_stack在安东尼的书中描述了关于C++并发似乎对我来说,同样aplies也是std::shared_ptr,因为功能,如std::atomic_load,std::atomic_compare_exchnage_weak被应用到的实例std::shared_ptr.

template <class T>
class lock_free_stack
{
public:
  void push(const T& data)
  {
    const std::shared_ptr<node> new_node = std::make_shared<node>(data);
    new_node->next = std::atomic_load(&head_);
    while (!std::atomic_compare_exchange_weak(&head_, &new_node->next, new_node));
  }

  std::shared_ptr<T> pop()
  {
    std::shared_ptr<node> old_head = std::atomic_load(&head_);
    while(old_head &&
          !std::atomic_compare_exchange_weak(&head_, &old_head, old_head->next));
    return old_head ? old_head->data : std::shared_ptr<T>();
  }

private:
  struct node
  {
    std::shared_ptr<T> data;
    std::shared_ptr<node> next;

    node(const T& data_) : data(std::make_shared<T>(data_)) {} …
Run Code Online (Sandbox Code Playgroud)

c++ concurrency smart-pointers atomic c++11

21
推荐指数
3
解决办法
6909
查看次数

是否可以在智能指针管理的内存上进行新的放置?

上下文

出于测试目的,我需要在非零内存上构造一个对象.这可以通过以下方式完成:

{
    struct Type { /* IRL not empty */};
    std::array<unsigned char, sizeof(Type)> non_zero_memory;
    non_zero_memory.fill(0xC5);
    auto const& t = *new(non_zero_memory.data()) Type;
    // t refers to a valid Type whose initialization has completed.
    t.~Type();
}
Run Code Online (Sandbox Code Playgroud)

由于这很繁琐且多次,我想提供一个函数,返回一个指向这样一个Type实例的智能指针.我想出了以下内容,但我担心隐藏在某处的未定义行为.

以下程序是否定义明确?特别是,std::byte[]已经分配了a但是Type同等大小的问题是一个问题吗?

#include <cstddef>
#include <memory>
#include <algorithm>

auto non_zero_memory(std::size_t size)
{
    constexpr std::byte non_zero = static_cast<std::byte>(0xC5);

    auto memory = std::make_unique<std::byte[]>(size);
    std::fill(memory.get(), memory.get()+size, non_zero);
    return memory;
}

template <class T>
auto on_non_zero_memory()
{
    auto memory = non_zero_memory(sizeof(T));
    return …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers undefined-behavior language-lawyer c++17

21
推荐指数
2
解决办法
1591
查看次数

我应该删除移动构造函数和智能指针的移动分配吗?

我正在实现一个简单的智能指针,它基本上跟踪它处理的指针的引用数量.

我知道我可以实现移动语义,但我不认为复制智能指针非常便宜.特别是考虑到它引入了产生令人讨厌的错误的机会.

这是我的C++ 11代码(我省略了一些不必要的代码).欢迎提出一般性意见.

#ifndef SMART_PTR_H_
#define SMART_PTR_H_

#include <cstdint>

template<typename T>
class SmartPtr {
private:
    struct Ptr {
        T* p_;
        uint64_t count_;
        Ptr(T* p) : p_{p}, count_{1} {}
        ~Ptr() { delete p_; }
    };
public:
    SmartPtr(T* p) : ptr_{new Ptr{p}} {}
    ~SmartPtr();

    SmartPtr(const SmartPtr<T>& rhs);
    SmartPtr(SmartPtr<T>&& rhs) =delete;

    SmartPtr<T>& operator=(const SmartPtr<T>& rhs);
    SmartPtr<T>& operator=(SmartPtr<T>&& rhs) =delete;

    T& operator*() { return *ptr_->p_; }
    T* operator->() { return ptr_->p_; }

    uint64_t Count() const { return ptr_->count_; }

    const T* …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers move-semantics c++11

20
推荐指数
1
解决办法
3006
查看次数