标签: shared-ptr

查找boost :: shared_ptr循环引用

有没有找到shared_ptr的循环引用的提示/技巧?

这是我想要找到的例子 - 不幸的是我似乎无法在我的代码中找到循环.

struct A
{
  boost::shared_ptr<C> anC;
};

struct B
{
  boost::shared_ptr<A> anA;
};

struct C
{
  boost::shared_ptr<B> anB;
};
Run Code Online (Sandbox Code Playgroud)

c++ boost memory-leaks shared-ptr

9
推荐指数
2
解决办法
2475
查看次数

C++/Qt如何 - 内存分配有效?

我最近开始为自己调查Qt并提出以下问题:

假设我有一些QTreeWidget* widget.在某些时刻,我想添加一些项目,这是通过以下调用完成的:

QList<QTreeWidgetItem*> items;

// Prepare the items
QTreeWidgetItem* item1 = new QTreeWidgetItem(...);
QTreeWidgetItem* item2 = new QTreeWidgetItem(...);
items.append(item1);
items.append(item2);

widget->addTopLevelItems(items);
Run Code Online (Sandbox Code Playgroud)

到目前为止它看起来还不错,但我实际上并不了解谁应该控制对象的生命周期.我应该用一个例子解释一下:

让我们说,另一个函数调用widget->clear();.我不知道这个调用下面会发生什么,但我确实认为,内存分配item1item2没有得到安置在这里,因为他们的OWNAGE实际上并没有转移.而且,砰的一声,我们有内存泄漏.

问题如下 - 确实Qt可以为这种情况提供一些东西吗?我可以使用boost::shared_ptr或任何其他智能指针,并写出类似的东西

shared_ptr<QTreeWidgetItem> ptr(new QTreeWidgetItem(...));
items.append(ptr.get());
Run Code Online (Sandbox Code Playgroud)

但我不知道Qt本身是否会尝试delete对我的指针进行显式调用(因为我将它们声明为shared_ptr管理状态,这将是灾难性的).

你会如何解决这个问题?也许一切都很明显,我想念一些非常简单的东西?

c++ memory qt memory-leaks shared-ptr

9
推荐指数
1
解决办法
3270
查看次数

"单一分配"对于boost :: make_shared意味着什么

make_shared的boost文档中,它说:

除了方便和风格之外,这样的函数也是异常安全且相当快的,因为它可以对对象及其相应的控制块使用单个分配,从而消除了shared_ptr的构造开销的很大一部分.

我不明白"单一分配"的含义,这是什么意思?

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

9
推荐指数
1
解决办法
873
查看次数

指定移动后是否为任何标准类的状态?

如果我move shared_ptr'进shared_ptr''b'是'a'保证为空?

指定移动后是否为任何标准类的状态?

c++ shared-ptr c++11

9
推荐指数
2
解决办法
271
查看次数

将shared_ptr <T>转换为shared_ptr <void>

我有一个结构:

struct Params {
   std::shared_ptr<void> user_data;
   /* ... */
};
Run Code Online (Sandbox Code Playgroud)

我想这样使用它:

int main() {
  std::shared_ptr<SpecializedParams> sp(new SpecializedParams(100));
  Params params;
  /* ... */
  params.user_data = std::static_pointer_cast<void>(sp); 
  /* ... */
  std::shared_ptr<SpecializedParams> sp2 = 
    std::static_pointer_cast<SpecializedParams>(
      params.user_data
    );
  /* ... */
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这有效且安全吗?

c++ casting shared-ptr c++11

9
推荐指数
1
解决办法
1457
查看次数

是否可以将boost shared_ptr从C++传递到Python并返回到C++

我有一个在C++中的shared_ptr中保存的对象.该对象是通过python中的python绑定访问的,并传递给另一个试图保持它的绑定C++函数.看来,当对象从C++转到Python时,它会从shared_ptr转换为python对象.然后,当它返回到C++时,它将从python对象转换为新的shared_ptr,但是这个shared_ptr与初始持有shared_ptr无关.

是否可以设置boost-python绑定,以便从python对象到shared_ptr的转换引用原始的shared_ptr内部?

下面是我用来显示问题的删节代码.

在此示例中,对象最初保存在名为s_inital的shared_ptr中.它是通过getSharedPtr函数从python中获取的,然后通过putSharedPtr函数推回到C++中.在putSharedPtr里面,它被复制到weak_ptr s_copied中.检查调试器中的指针显示putSharedPtr中使用的shared_ptr与s_initial没有相同的引用计数内部.最后的断言将触发,因为弱指针s_copied仅与单个强指针(putSharedPtr中使用的指针)相关,并且一旦putSharedPtr完成,该指针就被破坏了.

static shared_ptr<Captured> s_initial;
static weak_ptr<Captured> s_copied;

class UseSharedPtr
{
public:
    shared_ptr<Captured> getSharedPtr()
    {
        return s_initial;
    }

    void putSharedPtr(shared_ptr<Captured> ptr)
    {
        s_copied = ptr;
    }
};


BOOST_PYTHON_MODULE(test)
{
    class_<Captured, shared_ptr<Captured>, boost::noncopyable>("Captured", no_init);
    class_<UseSharedPtr, boost::noncopyable>("UseSharedPtr", init<>())
        .def("getSharedPtr", &UseSharedPtr::getSharedPtr)
        .def("putSharedPtr", &UseSharedPtr::putSharedPtr)
    ;
}



    s_initial = make_shared<Captured>();

    const char* chunk = "\
from test import UseSharedPtr \n\
x = UseSharedPtr() \n\
ptr = x.getSharedPtr() \n\
x.putSharedPtr(ptr)\n\
del x \n\
del ptr \n\
";
    object result = exec(chunk, mainNamespace, mainNamespace); …
Run Code Online (Sandbox Code Playgroud)

boost shared-ptr boost-python

9
推荐指数
1
解决办法
1322
查看次数

从unique_ptr <T []>初始化shared_ptr <T>

[跟进这个问题]

最近,我一直在处理一些关于c风格数组的智能指针.我最终做了推荐的事情,并使用智能指针代替向量,但在那段时间,我得到了一些建议:不要使用shared_ptr<T>对象来管理最初制作的数组,make_unique<T[]>因为它不会调用delete[]而是delete.

这对我来说似乎不合逻辑,我检查了Coliru和标准:


这段代码:

#include <iostream>
#include <memory>

int main()
{
    std::cout << "start!\n";
    auto customArrayAllocator = [](unsigned int num){
        std::cout << "custom array allocator\n";
        return new int[num];
    };

    std::cout << "allocator constructed\n";

    auto customArrayDeleter = [](int *ptr){
        std::cout << "custom array deleter\n";
        delete[] ptr;
    };

    std::cout << "deleter constructed\n";

    std::unique_ptr<int[], decltype(customArrayDeleter)>
        myUnique(customArrayAllocator(4), customArrayDeleter);

    std::cout << "unique_ptr constructed\n";

    std::shared_ptr<int>
        myShared = std::move(myUnique);

    std::cout << "shared_ptr constructed\n";
}
Run Code Online (Sandbox Code Playgroud)

产生这个输出: …

c++ shared-ptr unique-ptr c++14

9
推荐指数
1
解决办法
1052
查看次数

std :: shared_ptr和dlopen(),避免未定义的行为

dlopen()是一个C函数,用于在运行时动态加载共享库.因此,如果您不熟悉,该模式是:

  • 打电话dlopen("libpath", flag)void *handle图书馆
  • 打电话从图书馆dlsym(handle, "object_name")得到void *object你想要的东西
  • 做你想做的事 object
  • 调用dlclose (handle)卸载库.

在C++中,这是所谓的别名构造函数的完美用例std::shared_ptr.模式变为:

  • 构造一个std::shared_ptr<void> handlefrom dlopen("libpath", flag)将在调用dlclose()析构函数时调用
  • 构建一个std::shared_ptr<void> objectfrom handledlsym(handle, "object_name")
  • 现在我们可以通过object任何我们想要的地方,完全忘记handle; 当object调用析构函数时,无论何时发生,dlclose()都会自动调用

绚丽的图案,效果很好.但是有一个小问题.上面的图案需要从铸void*whatever_type_object_is*.如果"object_name"引用一个函数(考虑到用例,它大部分时间都是这样),这是未定义的行为.

在C中,有一个黑客来解决这个问题.从dlopen手册页:

// ...
void *handle;    
double (*cosine)(double);
// ...
handle = dlopen("libm.so", RTLD_LAZY);
// ...

/* Writing: …
Run Code Online (Sandbox Code Playgroud)

c++ shared-libraries shared-ptr undefined-behavior c++11

9
推荐指数
1
解决办法
1031
查看次数

为什么shared_ptr实现中的ref_count是int*

我已经看到了几个shared_ptr的实现,例如这里.所有人都宣称ref_countint*.我不明白,如果只是一个,我们会失去什么int.谢谢!

template <class T>
class shared_ptr {
    T* ptr;
    int* ref_count;

    /**
     * Initializes the ref count used for tracking the usage.
     */
    void initialize_ref_count() {
        if (ref_count != nullptr)
            return;
        try {
            ref_count = new int;
            *ref_count = 1;
        }
        catch (std::bad_alloc& e) {
            std::cerr << "Memory allocation error: " << e.what();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

c++ shared-ptr

8
推荐指数
1
解决办法
851
查看次数

C++删除了new运算符但可以创建shared_ptr

我试着寻找答案,但找不到任何有助于理解幕后发生的事情.

假设我们有以下内容:

class Base
{
public:
    virtual int request() = 0; 
    void* operator new(long unsigned int size) = delete;
};


class Derived final : public Base
{
public:
    int request() override;
};

int Derived::request()
{
    return 2;
}
Run Code Online (Sandbox Code Playgroud)

在基类上,我删除了new运算符,因为我不想创建指针.我知道它可能没有任何意义,它只是一个实验.

当我调用g ++时,给我一个编译错误,告诉我删除了新的运算符.正是我所期待的.

int main()
{
    auto d =  std::make_unique<Derived>();
    int value = d->request();
    std::cout << "Request value is " << value << "." << std::endl;

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

但是,如果我创建一个shared_ptr,代码编译并运行正常.

    auto d =  std::make_shared<Derived>();
Run Code Online (Sandbox Code Playgroud)

为什么在创建共享指针时此代码有效.在这种情况下,运营商没有被使用?

c++ shared-ptr new-operator

8
推荐指数
1
解决办法
194
查看次数