关于从原始指针创建shared_ptr时文档描述与实际冲突的疑问
微软官方文档提到,从原始指针创建新的shared_ptr时,该新shared_ptr与原实例独立且不控制底层资源,但实际编写的代码却出现了双重释放错误,Stack Overflow相关案例也显示这种操作会导致资源被两次删除,因此对文档描述的含义存在疑问。
测试代码
void f(int* ptr) { shared_ptr<int> sptr(ptr); cout << "sptr in f: " << sptr.get() << endl; } int main() { auto sp1 = make_shared<int>(1); cout << "sp1 in main: " << sp1.get() << endl; f(sp1.get()); return 0; }
错误输出
sp1 in main: 0x6000016f5138 sptr in f: 0x6000016f5138 a.out(12083,0x119097600) malloc: *** error for object 0x6000016f5138: pointer being freed was not allocated a.out(12083,0x119097600) malloc: *** set a breakpoint in malloc_error_break to debug zsh: abort ./a.out
问题解析与解决
错误原因
微软文档的描述有隐藏前提,容易造成误解。正确逻辑是:
- 如果原始指针没有被任何智能指针管理,用它创建shared_ptr时,新的shared_ptr会接管资源控制权;
- 但如果原始指针已经被另一个shared_ptr(比如示例里的sp1)管理,此时再用这个指针创建新的shared_ptr,两个shared_ptr会各自维护独立的引用计数,互相不知道对方的存在。
示例里,sp1和sptr都认为自己是这块内存的唯一管理者:函数f结束时sptr销毁,释放一次内存;main函数结束时sp1销毁,又尝试释放同一块内存,直接触发双重释放错误。
正确写法
要传递shared_ptr的共享所有权,直接传shared_ptr对象即可,这样引用计数会同步增加:
void f(shared_ptr<int> sptr) { cout << "sptr in f: " << sptr.get() << endl; } int main() { auto sp1 = make_shared<int>(1); cout << "sp1 in main: " << sp1.get() << endl; f(sp1); return 0; }
这样所有共享的shared_ptr会共用同一个引用计数,只有当最后一个shared_ptr销毁时,才会释放底层资源,不会出现重复释放的问题。
对微软文档的澄清
微软文档说的“新shared_ptr与原实例独立且不控制底层资源”,应该是指原始指针未被智能指针管理的场景——此时不存在“原智能指针实例”,新shared_ptr自然和不存在的实例独立,并且接管原本无主的资源。文档没明确强调这个前提,才导致了误解。
内容的提问来源于stack exchange,提问作者yokus
相关产品推荐
相关产品推荐

