我一直假设std::move()a上会std::shared_ptr窃取指针并将原始指针设置为nullptr-从而不增加引用计数。在我的世界中似乎并非如此。
设置:
MacOS,g ++ -version =>“ Apple LLVM版本10.0.1(clang-1001.0.46.3)”
代码:
#include <cstdio>
#include <memory>
class Thing { public: Thing(int N) : value(N) {} int value; };
void print(const char* name, std::shared_ptr<Thing>& sp)
{ printf("%s: { use_count=%i; }\n", name, (int)sp.use_count()); }
int main(int argc, char** argv) {
std::shared_ptr<Thing> x(new Thing(4711));
print("BEFORE x", x);
std::shared_ptr<Thing> y = std::move(x);
y->value = 4712;
print(" AFTER x", x);
print(" AFTER y", y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
编译( …
我有一个相当复杂的多线程应用程序(服务器),由于断言,有时会崩溃:
/usr/include/boost/smart_ptr/shared_ptr.hpp:418: T* boost::shared_ptr< <template-parameter-1-1> >::operator->() const [with T = msg::Player]: Assertion `px != 0' failed.
Run Code Online (Sandbox Code Playgroud)
我一直无法确定原因,并想知道这是一个问题与boost :: shared_ptr或它是我吗?
我尝试了g ++ 4.4.3-4ubuntu5和llvm-g ++(GCC)4.2.1优化而没有优化和libboost1.40-dev(= 1.40.0-4ubuntu4).
我有一个问题.我们可以直接获得共享指针指向的对象吗?或者我们应该通过get()调用获取底层RAW指针然后访问相应的对象?
好的,首先是一些可能相关的事情:
我在C++ 11模式下使用Clang 3.1编译器,标准库设置为libc ++.
我正在尝试熟悉C++ 11,并且这样做我遇到的行为似乎很奇怪.它可能是Clang或libc ++的怪癖,但我不能说C++标准,我无法访问其他支持C++ 11的编译器,所以我无法检查它,我搜索了互联网和Stack Overflow在没有发现任何相关的情况下尽我所能......所以我们走了:
当使用shared_ptr/unique_ptr为简单资源实现RAII时,它们的行为似乎与删除时的空指针不同.我意识到通常没有必要删除空指针,但我原本期望这两个STL智能指针之间的行为至少匹配.
对于特定情况,请考虑以下代码:
{
auto Deleter = [](void *){cout << "It's later!" << endl;};
shared_ptr<void> spDoSomethingLater(nullptr, Deleter);
unique_ptr<void, void (*)(void *)> upDoSomethingLater(nullptr, Deleter);
cout << "It's now!" << endl;
}
Run Code Online (Sandbox Code Playgroud)
我原本期望得到以下输出之一:
a)如果两个删除器都被调用,即使指针为空:
"It's now!"
"It's later!"
"It's later!"
Run Code Online (Sandbox Code Playgroud)
b)如果由于指针为空而未调用任何删除器:
"It's now!"
Run Code Online (Sandbox Code Playgroud)
但我没有观察到这些情况.相反,我观察到:
"It's now!"
"It's later!"
Run Code Online (Sandbox Code Playgroud)
这意味着正在调用一个但不是另一个删除者.经过进一步研究,我发现无论是否包含null值,都会调用shared_ptr的删除器,但只有在不包含空值的情况下才会调用unique_ptr的删除器.
我的问题:这实际上是标准规定的正确行为吗?如果是这样,为什么两种STL类型之间的指定行为会以这种方式不同?如果没有,这是一个我应该向libc ++报告的错误吗?
我刚刚意识到阅读这个页面,std :: shared_ptr的构造函数与单个指针参数不是noexcept.
因此,以下代码包含可能的内存泄漏:
std::shared_ptr<int> p3 (new int);
Run Code Online (Sandbox Code Playgroud)
原因是可能发生两次分配:
这里有两个问题:
如果第二个分配抛出异常,第一个分配的内存泄漏,这是真的吗?
如果答案是肯定的:
使用std :: shared_ptr的正确习惯用法是什么?
这是一个智能指针:std::shared_ptr<char> p(new char[size])表示填充原始二进制文件内容的数组.在整个数组从文件复制到RAM之后(并且仅在之后),我可以解析它,在此期间我检索一些头信息(几个第一个dwords).然后是实际数据.
在没有提供更多上下文的情况下,将所提到的共享指针设置为实际数据开头的新地址非常方便.该地址仍处于已分配的内存中.但如何设置而不失去它?
一个问题是(是/否):是否可以设置p偏移主流指针,而无需调用数据删除?
我有一个现有的变量,例如
int a = 3;
Run Code Online (Sandbox Code Playgroud)
我现在如何才能创建一个boost::shared_ptr到a?例如:
boost::shared_ptr< int > a_ptr = &a; // this doesn't work
Run Code Online (Sandbox Code Playgroud) 我有把std :: shared_ptr作为参数的函数,所以我被迫使用std :: shared_ptr,但我传递给函数的对象没有动态分配.如何在std :: shared_ptr中包装对象并让std :: shared_ptr不调用delete.
我的接口函数返回一个指向对象的指针.用户应该拥有该对象的所有权.我不想返回Boost.shared_ptr,因为我不想强制客户端使用boost.但是,在内部,我想将指针存储在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.它是否也会阻止引用计数递增?
如果这无关紧要,我更喜欢哪个选项?做出这样的决定时,我应该考虑其他事情吗?
shared-ptr ×10
c++ ×9
c++11 ×4
boost ×2
boost-thread ×1
macos ×1
memory-leaks ×1
nullptr ×1
shared ×1
unique-ptr ×1