shared_ptr的几个思考

博客讨论了在C++中尝试将`shared_ptr`转换为`void*`作为C接口的handle导致的编译错误。然后提到了通过new创建普通指针并转换为`shared_ptr`的方法,但指出这种方式可能导致内存泄漏和段错误,因为C接口手动delete对象会破坏`shared_ptr`的管理。最后,代码示例展示了这个问题,显示了两次析构导致的段错误。
摘要由CSDN通过智能技术生成

1、因为涉及到C++转换C接口,就想着能不能简单点,把shared_ptr转换为void *作为一个handle

      结果证明:编译错误       

test_shared_ptr.cc: In function ‘void convert_shared_ptr_to_void()’:
test_shared_ptr.cc:26:14: error: cannot convert ‘std::shared_ptr<Test>’ to ‘void*’ in initialization
  void *tmp = g_aa;

2、上面不能用shared_ptr来转换为handle,那就只能new一个普通指针作为handle了,然后再转换为shared_ptr,

      后面就涉及到C接口对称,是否需要在C接口里手动destroy new出来的对象呢

     答案:不可以。会导致多次释放,产生端错误

      代码如下:

#include <iostream>
#include <memory>
using namespace std;

class Test {
 public:
  Test(){ cout << "Test create" << endl; }
  ~Test() { cout << "destroy Test" << endl; }
  int Get() { cout << " Get" << endl; }
};

shared_ptr<Test> g_aa;
void *create_func() {
	Test *test = new Test();
	g_aa = shared_ptr<Test>(test);
	cout << " func: test = " <<  test << endl;
	cout << " func: gaa = " <<  g_aa << endl;
	return (void *)test;
}

void destroy(void *aa) {
	delete (Test*)aa;
}


int main () {
	Test* aa = (Test *)create_func();
	cout << " main: test = " <<   aa << endl;

    cout << g_aa.use_count() << endl;
	destroy(aa);
    cout << g_aa.use_count() << endl;

}

运行结果:显示两次destroy,所以出现段错误

Test create
 func: test = 0x13aac20
 func: gaa = 0x13aac20
 main: test = 0x13aac20
1
destroy Test
1
destroy Test
*** Error in `./a.out': double free or corruption (fasttop): 0x00000000013aac20 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777f5)[0x7f303a8ef7f5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8038a)[0x7f303a8f838a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f303a8fc58c]
./a.out[0x4016ce]
./a.out[0x4011bc]
./a.out[0x4010bd]
./a.out[0x401060]
./a.out[0x40107c]
/lib/x86_64-linux-gnu/libc.so.6(+0x3a008)[0x7f303a8b2008]
/lib/x86_64-linux-gnu/libc.so.6(+0x3a055)[0x7f303a8b2055]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf7)[0x7f303a898847]
./a.out[0x400c49]
======= Memory map: ========
00400000-00403000 r-xp 00000000 08:02 39977613                           /home/mi/work/test/a.out
00602000-00603000 r--p 00002000 08:02 39977613                           /home/mi/work/test/a.out
00603000-00604000 rw-p 00003000 08:02 39977613                           /home/mi/work/test/a.out
01399000-013cb000 rw-p 00000000 00:00 0                                  [heap]
7f3034000000-7f3034021000 rw-p 00000000 00:00 0 
7f3034021000-7f3038000000 ---p 00000000 00:00 0 
7f303a56f000-7f303a677000 r-xp 00000000 08:02 14942394                   /lib/x86_64-linux-gnu/libm-2.23.so
7f303a677000-7f303a876000 ---p 00108000 08:02 14942394                   /lib/x86_64-linux-gnu/libm-2.23.so
7f303a876000-7f303a877000 r--p 00107000 08:02 14942394                   /lib/x86_64-linux-gnu/libm-2.23.so
7f303a877000-7f303a878000 rw-p 00108000 08:02 14942394                   /lib/x86_64-linux-gnu/libm-2.23.so
7f303a878000-7f303aa38000 r-xp 00000000 08:02 14942390                   /lib/x86_64-linux-gnu/libc-2.23.so
7f303aa38000-7f303ac38000 ---p 001c0000 08:02 14942390                   /lib/x86_64-linux-gnu/libc-2.23.so
7f303ac38000-7f303ac3c000 r--p 001c0000 08:02 14942390                   /lib/x86_64-linux-gnu/libc-2.23.so
7f303ac3c000-7f303ac3e000 rw-p 001c4000 08:02 14942390                   /lib/x86_64-linux-gnu/libc-2.23.so
7f303ac3e000-7f303ac42000 rw-p 00000000 00:00 0 
7f303ac42000-7f303ac58000 r-xp 00000000 08:02 14946764                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f303ac58000-7f303ae57000 ---p 00016000 08:02 14946764                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f303ae57000-7f303ae58000 rw-p 00015000 08:02 14946764                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f303ae58000-7f303afca000 r-xp 00000000 08:02 18352567                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f303afca000-7f303b1ca000 ---p 00172000 08:02 18352567                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f303b1ca000-7f303b1d4000 r--p 00172000 08:02 18352567                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f303b1d4000-7f303b1d6000 rw-p 0017c000 08:02 18352567                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f303b1d6000-7f303b1da000 rw-p 00000000 00:00 0 
7f303b1da000-7f303b200000 r-xp 00000000 08:02 14942401                   /lib/x86_64-linux-gnu/ld-2.23.so
7f303b3da000-7f303b3e0000 rw-p 00000000 00:00 0 
7f303b3fe000-7f303b3ff000 rw-p 00000000 00:00 0 
7f303b3ff000-7f303b400000 r--p 00025000 08:02 14942401                   /lib/x86_64-linux-gnu/ld-2.23.so
7f303b400000-7f303b401000 rw-p 00026000 08:02 14942401                   /lib/x86_64-linux-gnu/ld-2.23.so
7f303b401000-7f303b402000 rw-p 00000000 00:00 0 
7ffc643a6000-7ffc643c7000 rw-p 00000000 00:00 0                          [stack]
7ffc643f6000-7ffc643f9000 r--p 00000000 00:00 0                          [vvar]
7ffc643f9000-7ffc643fb000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
已放弃 (核心已转储)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值