关于boost中shared_ptr的疑问
shared_ptr被很多人说成是最好用的智能指针。今天刚刚开始学习就遇到了一个问题。shared_ptr的传参数问题。比如,对于CreateThread函数的第4个参数可以传一个lpvoid指针作为参数穿进去的,也就是任意类型的指针,但是不能够将 shared_ptr作为lpvoid传入。当然可以将shared_ptr中的指针提取出来,但是这样就导致计数并不记录比如下面的程序片段:
typedef struct InsertData
{
int iNum;
char cData[10];
InsertData()
{
iNum = 10;
ZeroMemory(cData, 10);
}
}INSERT, *PINSERT
//////////////////////////////////////////////////////////////////////
void fun()
{
INSERT* pInsertData = new INSERT;
boost::shared_ptr<INSERT> shTest(pInsertData);
char cData[5] = {'a','b','c','d'};
memcpy(pInsertData->cData, cData, 4);
m_hThread = CreateThread(NULL, 0, ThreadFunc,(LPVOID)&(*shTest), NULL, 0);
Sleep(2000);
}
DWORD ThreadFunc(LPVOID pParam)
{
boost::shared_ptr<INSERT> pThreadShared((INSERT*)pParam);
int i = 0;
for (int j = 0; j < 10; j++)
{
i++;
TRACE("第%d次输出%s\n", i, pThreadShared->cData);
Sleep(1000);
}
Sleep(5000);
return 0;
}
这个程序执行结果显示只有第一次和第二次输出结果正确,之后的就是错误指针。意味着计数没有将这个参数传递记录,fun函数结束后就已经释放了。那么我想问有什么方法可以让它记录呢。当然你可以说直接使用boost的多线程,但是在实际工程中有很多第三方提供的借口参数就是void*类型,是不是这种情况下智能指针就没有作用了呢。求教各位大侠
------解决方案--------------------share_ptr被你这么一用完全就错了。
shared_ptr<INSERT> pThreadShared((INSERT*)pParam);
你在这里面又创建一个shared_ptr对象这使得两个shared_ptr指向同一个对象,这意味着pThreadShared的销毁导致线程外的那个里面的原生指针悬空了。
------解决方案--------------------不要和纯C接口的操作系统api混用C++的容器、智能指针。
------解决方案--------------------建议封装你的函数给别人用 你的函数里可以用boost
------解决方案--------------------用boost的shared_ptr,自然得用boost的thread.
C/C++ code
void thrd_func(shared_ptr<int> sp)
{
}
int test()
{
shared_ptr<int> sp(new int(10));
boost::thread thrd(boost::bind(thrd_func, sp));
thrd.join();
}