标签: smart-pointers

如何增加 std::shared 指针的所有权数量

我有一个具有指针作为成员的结构:

struct MyStruct {
  char *ptr;
}
Run Code Online (Sandbox Code Playgroud)

我想在一个范围内初始化 ptr,然后能够在该范围之外使用它:

{ // scope 0
    { //scope 1

        { // scope 2
            mystruct.ptr = new char[100];
        }

        // mystruct.ptr still lives here
    }

    // i dont need mystruct anymore
    delete[] mystruct.ptr;
}
Run Code Online (Sandbox Code Playgroud)

但后来我必须删除它,这很容易出错,我宁愿避免这样做。所以我想到使用std::shared_ptr.

{ // scope 0
    { //scope 1

        { // scope 2
            auto a = std::make_shared<char>(new char[100]);
            mystruct.ptr = a.get(); // ??????? HOW TO ASSIGN
        }

        // mystruct.ptr still SHOULD live here
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 那么,我该怎么办呢?我应该如何将shared_ptr分配给mystruct.ptr以使所有权计数变为2?我看到 get() 不起作用,因为它只是传递指针但不给出所有权,因此它被删除。

  • 如您所见,这里的主要动机是延长寿命,因此我对其他做法持开放态度。也许我在这里使用shared_ptr的想法是错误的?

c++ smart-pointers object-lifetime lifetime-scoping

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

unique_ptr 和带有 C API 的库,带有指向指针函数参数的指针

假设我有一个库,它初始化一个对象,如下所示:

Type *object;

lib_init(&object); // lib_init takes Type **object as the parameter
Run Code Online (Sandbox Code Playgroud)

那么,如果我想在使用智能指针的代码中使用该库该怎么办?这是正确的方法吗?

Type *pObject;
lib_init(&pObject);
unique_ptr<Type> object(nullptr);
object.reset(pObject);
Run Code Online (Sandbox Code Playgroud)

或者有一个聪明的方法来做到这一点?

c++ pointers smart-pointers

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

作用域 std::unique_ptr 强制转换

我目前正在使用智能指针编写一些代码,其中在许多点上有必要将这些指针强制转换为其基本类型并将它们作为 const 参数传递给函数。目前我正在使用shared_ptr和标准指针转换函数来实现这一点,但这似乎效率低下(因为每次转换至少需要一个CAS)并且还具有误导性(因为我们没有建模共享关系,父级是唯一的所有者)物体)。

因此,我想出了以下内容,但想检查它确实安全,还是有一些边缘情况会破坏它?

template <typename ToType, typename FromType>
class FTScopedCastWrapper {
public:
    explicit FTScopedCastWrapper(std::unique_ptr<FromType>& p) : from_ptr_(&p) {
        auto d = static_cast<ToType *>(p.release());
        to_ptr_ = std::unique_ptr<ToType>(d);
    }

    ~FTScopedCastWrapper() {
        auto d = static_cast<FromType *>(to_ptr_.release());
        (*from_ptr_) = std::unique_ptr<FromType>(d);
    }

    const std::unique_ptr<ToType>& operator()() {
        return to_ptr_;
    }


    // Prevent allocation on the heap
    void* operator new(size_t) = delete;
    void* operator new(size_t, void*) = delete;
    void* operator new[](size_t) = delete;
    void* operator new[](size_t, void*) = delete;

private:
    std::unique_ptr<FromType>* from_ptr_;
    std::unique_ptr<ToType> to_ptr_;
}; …
Run Code Online (Sandbox Code Playgroud)

c++ pointers smart-pointers c++11

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

用另一个 unique_ptr 替换向量中的 unique_ptr 对象

我想用另一个对象替换该索引处的 unique_ptr 对象,这本质上是“删除”向量中当前的指针,并将 classObj 移动到该位置。

std::unique_ptr<ClassName> classObj(new className());
classNameStorage[5] = classObj; // classNameStorage.size() > 5
Run Code Online (Sandbox Code Playgroud)

上面的代码,使用赋值运算符是无效的。

c++ smart-pointers unique-ptr c++11

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

C++对std::shared_ptr引用的reinterpret_cast进行优化

您有两个类AnimalDog(其中Dog继承自Animal),并且您经常会遇到一种情况,您经常期待动物,但发送的是狗的实例。在我的特定情况下,我经常将强指针(std::shared_ptr<Dog>)投射到动物期望函数(std::shared_ptr<Animal>)。

如果我们接受我们可以将函数参数设置为引用(std::shared_ptr<Animal>&避免争论为什么不应该将强指针作为引用参数,因为担心更改线程的所有权),我认为我们在内存方面可以安全地强制转换std::shared_ptr<Dog> dog使用reinterpret_cast<std::shared_ptr<Animal>&>(dog),对吗?

如果是这样,除了线程问题之外还会出现什么问题?比如引用计数的变化?

需要明确的是,我们的目的是提供一种可在许多情况下使用的解决方案,在这些情况下,一次强制转换并不是真正可行的解决方案。更重要的是,有许多对象需要铸造。此外,忽略这一点std::unique_ptr可能是也可能不是更好的解决方案。

std::shared_ptr添加最后一个要求 -在通用序列化器类函数是虚拟的因此无法模板化的情况下,使用普通指针将不允许我更改原始指针。

c++ smart-pointers shared-ptr reinterpret-cast c++11

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

在双向链表中使用智能指针

以下是我对智能指针的了解

  1. shared_ptr是一个智能指针,多个shared_ptr可以指向堆中的一个对象。即使删除了共享指针之一,只要引用计数大于零,堆中的对象就不会被销毁。
  2. 一个weak_ptr也指向堆中的一个对象,但它不会增加该对象的引用计数
  3. 我们可以使用weak_ptr来打破循环引用

在双向链表的情况下,我们有两个指针指向前一个和下一个节点。我们在实现中使用了shared_ptr和weak_ptr。为什么我们不使用两个weak_ptr?

c++ pointers smart-pointers weak-ptr c++14

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

Bison 中的 std::shared_ptr 导致成员错误

我正在尝试通过使用来提高野牛的内存效率std::shared_ptr。我不想使用原始指针。我使用节点系统作为解析树,所以我定义YYTYPEstd::shared_ptr<Node>。用一些简单的语法运行它后,我得到编译错误:

C2039 'blockNode':不是 'std::shared_ptr' 的成员

我觉得这很奇怪,因为在 C++ 中运行的等效代码工作得很好

std::shared_ptr<Node> test = std::make_shared<BlockNode>();

我缺少什么?

需要

%code requires {
    typedef void* yyscan_t;
    #include "node.h"
    #include <memory>
    #define YYSTYPE std::shared_ptr<Node>
}
Run Code Online (Sandbox Code Playgroud)

联盟

%union {
    std::shared_ptr<BlockNode> blockNode;
    std::shared_ptr<TestNode> testNode;
}

%type <blockNode> input
%type <testNode> expr
Run Code Online (Sandbox Code Playgroud)

语法

%start program

%%

program : input { *result = $1; } // <- error here
        ;

input: '\n'      { $$ = std::make_shared<BlockNode>();} // <- error here
     ;

%%

Run Code Online (Sandbox Code Playgroud)

节点.h

class Node …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers bison flex-lexer

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

使用 make_shared&lt;U[]&gt;( std::size_t N )` 时出错

我正在尝试实现一个固定大小的多维数组,其大小在运行时确定。make_shared与( )的 (2) 重载template<class T> shared_ptr<T> make_shared(std::size_t N) // T is U[]。但是,我面临编译错误(日志如下)。shared如果我将s 更改为其对应项,则不会出现该错误unique。我的问题是,

\n
    \n
  • 这个错误是关于什么的?
  • \n
  • 为什么unique有效?
  • \n
  • 有更好的方法来实现这种运行时固定的多维数组容器吗?
  • \n
\n

最小工作示例:

\n
#include <memory>\n#include <iostream>\nint main() {\n    typedef int cell_t;\n    std::size_t x, y;\n    std::cin >> y >> x;\n    auto layout = std::make_shared<std::shared_ptr<cell_t[]>[]>(y);\n    for (std::size_t i = 0; i < y; i += 1) {\n        layout[i] = std::make_shared<cell_t[]>(x);\n    }\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

错误消息如下g++-10(为简洁起见,省略了注释)

\n
In file included …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers shared-ptr c++20

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

为什么在单独的行上调用函数会改变 C++ 中的结果?

似乎由于某种原因,当我尝试在同一行调用两个函数时,第一个函数从“.get()”接收 nullptr 作为第一个参数

getSomePtr(someUniquePtr.get(), someArray)->moveUniquePtr(std::move(someUniquePtr));
Run Code Online (Sandbox Code Playgroud)

但是,当将这些函数分成两行时,一切似乎都有效:

auto* somePtr = getSomePtr(someUniquePtr.get(), someArray);
somePtr->moveUniquePtr(std::move(someUniquePtr));
Run Code Online (Sandbox Code Playgroud)

为什么会出现这种情况?

c++ smart-pointers

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

在 C++ 中如何使用 make_unique 防止内存泄漏?

fn(unique_ptr<A>{new A{}},unique_ptr<B>{new B{}});
Run Code Online (Sandbox Code Playgroud)

很麻烦,因为A如果B在那里抛出异常,就会发生泄漏。

fn(make_unique<A>(),make_unique<B>());
Run Code Online (Sandbox Code Playgroud)

另一方面被认为是异常安全的。

问题:

为什么?使用make_unique如何防止内存泄漏make_unique做了
哪些默认的unique_ptr没有做的事情?

请帮帮我。
谢谢。

c++ memory-leaks smart-pointers unique-ptr

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