我有一个具有指针作为成员的结构:
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的想法是错误的?
假设我有一个库,它初始化一个对象,如下所示:
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)
或者有一个聪明的方法来做到这一点?
我目前正在使用智能指针编写一些代码,其中在许多点上有必要将这些指针强制转换为其基本类型并将它们作为 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) 我想用另一个对象替换该索引处的 unique_ptr 对象,这本质上是“删除”向量中当前的指针,并将 classObj 移动到该位置。
std::unique_ptr<ClassName> classObj(new className());
classNameStorage[5] = classObj; // classNameStorage.size() > 5
Run Code Online (Sandbox Code Playgroud)
上面的代码,使用赋值运算符是无效的。
您有两个类Animal和Dog(其中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添加最后一个要求 -在通用序列化器类函数是虚拟的因此无法模板化的情况下,使用普通指针将不允许我更改原始指针。
以下是我对智能指针的了解
在双向链表的情况下,我们有两个指针指向前一个和下一个节点。我们在实现中使用了shared_ptr和weak_ptr。为什么我们不使用两个weak_ptr?
我正在尝试通过使用来提高野牛的内存效率std::shared_ptr。我不想使用原始指针。我使用节点系统作为解析树,所以我定义YYTYPE为std::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) 我正在尝试实现一个固定大小的多维数组,其大小在运行时确定。make_shared与( )的 (2) 重载template<class T> shared_ptr<T> make_shared(std::size_t N) // T is U[]。但是,我面临编译错误(日志如下)。shared如果我将s 更改为其对应项,则不会出现该错误unique。我的问题是,
unique有效?最小工作示例:
\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}\nRun Code Online (Sandbox Code Playgroud)\n错误消息如下g++-10(为简洁起见,省略了注释)
In file included …Run Code Online (Sandbox Code Playgroud) 似乎由于某种原因,当我尝试在同一行调用两个函数时,第一个函数从“.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)
为什么会出现这种情况?
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++ ×10
smart-pointers ×10
c++11 ×3
pointers ×3
shared-ptr ×2
unique-ptr ×2
bison ×1
c++14 ×1
c++20 ×1
flex-lexer ×1
memory-leaks ×1
weak-ptr ×1