#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class test : public enable_shared_from_this<test> {
vector<shared_ptr<test>> vec;
public:
void addvec()
{
vec.emplace_back(shared_from_this());
}
~test() { cout << "destructing\n"; }
};
int main()
{
auto sp = make_shared<test>();
sp->addvec(); // when called, destructor is not invoked and
// LeakSanitizer reports a memory leak
}
Run Code Online (Sandbox Code Playgroud)
对象test由 管理std::shared_ptr,并且在调用 后addvec,第二个shared_ptr实例将存储在内部向量中 (ref_count == 2)。
但析构函数从未被调用,并且报告了内存泄漏。为什么是这样?
使用g++ -g -fsanitize=leak c.cpp
GCC 版本 12.2.1编译
通常,当强引用计数和弱引用计数都达到 0 时,智能指针(强指针或弱指针)将释放控制块。
我在弄清楚如何在以下场景中实现这一点时遇到问题:线程 A 持有强引用,线程 B 持有弱引用,两者都指向同一个块。
假设强引用正在被销毁,并且强引用计数已达到0,则引用析构函数将调用托管对象的析构函数。到目前为止,一切都很好。
但随后它会检查弱引用计数并根据该值决定释放该块。
在这里,我仍然看到线程 B 中的弱引用和线程 A 中的强引用之间可能存在竞争,从而两次释放该块。弱引用可能会自动将其弱引用计数减少到 0,但我不明白为什么强引用在弱引用释放并再次释放之前无法看到这个 0。
根据我的理解,当 const shared_ptr& 向上转换时,它会创建指向同一(转换)对象的基类的新共享指针。
#include <iostream>
#include <memory>
class Animal
{
};
class Cat : public Animal
{
};
void display(const std::shared_ptr<Animal>& animal)
{
std::cout << animal.use_count() << std::endl;
}
int main()
{
auto cat = std::make_shared<Cat>();
std::cout << cat.use_count() << std::endl;
display(cat);
std::cout << cat.use_count() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
上述代码的输出如下。
sujith@AKLJoincggDLEd:~/sujith$ g++ -std=c++17 main.cpp
sujith@AKLJoincggDLEd:~/sujith$ ./a.out
1
2
1
sujith@AKLJoincggDLEd:~/sujith$
Run Code Online (Sandbox Code Playgroud)
我的问题是哪个运营商执行此操作?对于其他引用向上转换,我们是否也可以获得相同的行为?或者是专门针对shared_ptr引用进行处理的?
感谢您对此进行调查。
因此,如果您想共享shared_ptr过去元素中的所有内容x,您可以编写如下内容:
int main(){
std::shared_ptr<float[]> _vals = std::make_unique<float[]>(70);
for(uint32_t i = 0; i < 10; ++i)
_vals[i] = i;
//range from 2 - end of _vals
// x = 2 in this case
std::shared_ptr<float[]> _partial(_vals, &_vals[2]);
for(uint32_t i = 0; i < 5; ++i)
std::cout<<_partial[i]<<" ";
std::cout<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以输出将是:
2 3 4 5 6
Run Code Online (Sandbox Code Playgroud)
所以_partial会指向从_vals.get() + 2到 的结尾_vals。但是,如果我想让它指向,例如(2-5), (70-end),我想知道是否可以分配地址来_partial完成此操作,该怎么办?例如,如果这有效:
2 3 4 5 6
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试编译它,我会收到错误: …
我使用boost shared_ptr来包装指针.但是我只能在test_shared_ptr()中获取正确的值,而在main()中,我得到了错误的值.
预期产量:
100
100实际产量:
100
-572662307
在这种情况下,指针似乎变得无效.有没有正确的方法来完成这项工作?提前致谢.
以下是源代码.
#include <memory>
#include <iostream>
class TestClass
{
public:
TestClass(int &i);
void print_i();
private:
int *_i;
};
TestClass::TestClass(int &i) : _i(&i)
{
}
void TestClass::print_i()
{
std::cout << *_i << std::endl;
}
void print_i(int &i)
{
std::cout << i << std::endl;
}
TestClass *test_shared_ptr()
{
std::tr1::shared_ptr<int> i(new int());
*i = 100;
print_i(*i);
return new TestClass(*i);
}
int main(int argc, char** argv)
{
TestClass *p = test_shared_ptr();
p->print_i();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在使用gcc 4.6.2.
我正在尝试在向量shared_ptr中推送back_back.
但gcc每次都给我一个错误.
这是我的代码行:
std::vector< std::tr1::shared_ptr<Process> > procs;
std::string line;
while (getline(file, line) && line.find(JobMask) != std::string::npos)
{
std::string procName = line.substr(line.find(JobMask) + JobMask.size());
std::vector<Instruction> procInstructions = extractProgram(file);
std::queue<int> procInputs = extractInputs(file);
if (!procInstructions.empty())
procs.push_back(std::make_shared<Process>(Process(procName, procInputs, procInstructions))); //line 51
}
return procs;
Run Code Online (Sandbox Code Playgroud)
我的gcc给出的错误是:
Process.cpp: In static member function 'static std::vector<std::tr1::shared_ptr<RMMIX::Process> > RMMIX::Process::createProcesses(const string&)':
Process.cpp:51:95: error: no matching function for call to 'std::vector<std::tr1::shared_ptr<RMMIX::Process> >::push_back(std::shared_ptr<RMMIX::Process>)'
Process.cpp:51:95: note: candidates are:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::tr1::shared_ptr<RMMIX::Process>, _Alloc = …Run Code Online (Sandbox Code Playgroud) 这段代码有什么问题,如何解决?
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <vector>
struct CTest
{
CTest()
{ std::cout << "ctor CTest" <<std::endl; }
~CTest()
{ std::cout << "dtor CTest" <<std::endl; }
};
struct CSlot
{
CSlot() : m_test(new CTest()), m_num(123)
{ }
~CSlot()
{
// m_test.reset(); // this line fixed the code but I don't know why
m_num = -1;
}
boost::shared_ptr<CTest> m_test;
int m_num;
};
int main()
{
std::vector<CSlot> testVector(1);
std::cout << "1" << std::endl;
new (&testVector[0]) CSlot();
// clear slot
testVector[0].~CSlot();
std::cout << …Run Code Online (Sandbox Code Playgroud) 这就是场景:我有一个名为Program的类,它包含三个shared_ptr:到顶点,几何和片段着色器.构造Shader对象时,它会使用glCreateShader创建着色器,并且还会对其进行编译.
Shader denstructor自动调用glDeleteShader.所以问题是,如果我执行以下操作:
原始副本也会失效,因为当副本被销毁时,它会调用glDeleteShader.我相信这是一个设计问题.
所以我通过使用指针避免了这个问题.现在,Program类包含着色器.我创建了一个方法,将shared_ptr返回到顶点,几何和片段Shader对象.我的疑问是:我应该像这样返回shared_ptr:
const shared_ptr<Shader>& getVertex_shader_ptr() const
{
return vertex_shader_ptr;
}
Run Code Online (Sandbox Code Playgroud)
或者像这样:
shared_ptr<Shader> getVertex_shader_ptr() const
{
return vertex_shader_ptr;
}
Run Code Online (Sandbox Code Playgroud)
我担心的是我上面描述的问题再次发生:shared_ptr被取消分配并且它使OpenGL着色器无效.
我一直很难找到类似这个问题的东西,所以我会问这里.
我有一个包含十几个源/头文件的项目.我遇到的主要问题是预定义我在命名空间中创建的类.代码如下:
"GlobalIncludes.h"
/*include dependencies and library headers...*/
/*[Note 1]How would I predefine the classes inside namespaces?*/
typedef std::tr1::shared_ptr<Class1> ClassPtr1;//[Note 2]
typedef std::tr1::shared_ptr<Class2> ClassPtr2;//[Note 2]
/*[Note 2]What is the correct way to predefine the shared_ptr's?*/
#include "Class1.h"
#include "Class2.h"
Run Code Online (Sandbox Code Playgroud)
"Class1.h"
namespace myNamespace
{
class Class1
{
/*variables and functions*/
void doSomething(...);
Class2 exampleObject;
};
}
Run Code Online (Sandbox Code Playgroud)
"Class2.h"
namespace myNamespace
{
class Class2
{
/*variables and functions*/
};
}
Run Code Online (Sandbox Code Playgroud)
如果这听起来有点令人困惑,我提前道歉......基本上我想知道是否有可能预定义namespace myNamespace同时声明shared_ptr的类.如果可以,我该如何做,并在源中正确使用它们?
我正在尝试像类一样编写一个boost-signal(作为学习c ++的实践).我发现当我使用时enable_shared_from_this,我总是在析构函数中崩溃.这是代码(我正在使用vs2012更新2):
对此有何评论?应该引起这个问题shared_from_this(),因为当我取消注释line(auto this_ = shared_from_this();)时signal_connection::disconnect,一切正常.
我知道在调用之前必须至少有一个有效的shared_ptr shared_from_this().我的代码应该满足这一点.
代码:
#include <memory>
#include <map>
class slot_manager;
class signal_connection: public std::enable_shared_from_this<signal_connection>
{
public:
signal_connection(slot_manager* manager)
:manager_(manager)
{}
public:
void disconnect() ;
private:
slot_manager* manager_;
};
class slot_manager
{
public:
typedef std::shared_ptr<signal_connection> connection_type;
typedef std::map<connection_type, int> map_type;
typedef map_type::value_type map_value_type;
public:
void connect(int slot)
{
std::shared_ptr<signal_connection> c(new signal_connection(this));
slots_.insert(map_value_type(c, slot));
}
~slot_manager()
{
auto iter = slots_.begin();
map_type::iterator iter2 = slots_.end();
while (iter …Run Code Online (Sandbox Code Playgroud) c++ ×10
shared-ptr ×10
c++11 ×3
c++17 ×1
casting ×1
class ×1
destructor ×1
gcc4 ×1
make-shared ×1
namespaces ×1
opengl-2.0 ×1
unique-ptr ×1
valgrind ×1