使用STL string慎用memcpy和void*

使用STL string慎用memcpy和void*

项目中常用STL的string,最近遇到些问题,罪魁祸首是memcpy和void*。

1、类中有string成员变量,如果不小心用memcpy拷贝了该类的对象,则string成员变量将被析构两次。这其实就是浅拷贝的错误,实在要用string,又要拷贝,只有自己实现拷贝函数。

struct stInfo
{
	int age;
	std::string name;
};
 
int main()
{
	stInfo info;
	info.name = "dandan";
 
	stInfo* p = new stInfo();
	memcpy(p, &info, sizeof(info));
 
	//...
	delete p;    //p指向的对象被正常删除,成员变量str被删除,string的析构函数被调用,其内存地址被释放
	return 0;
}    
//程序退出时,对象m被析构,string的析构函数被调用,同一块内存地址再次被释放,抛异常

Crash文件

*** Error in `./a.out': munmap_chunk(): invalid pointer: 0x00007fff70c42c58 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7ada4)[0x7f1aaf626da4]
./a.out[0x400ba8]
./a.out[0x400ad5]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f1aaf5cdb35]
./a.out[0x400999]
======= Memory map: ========
00400000-00401000 r-xp 00000000 fd:01 1070198                            /home/Test/a.out
00601000-00602000 r--p 00001000 fd:01 1070198                            /home/Test/a.out
00602000-00603000 rw-p 00002000 fd:01 1070198                            /home/Test/a.out
0198b000-019bd000 rw-p 00000000 00:00 0                                  [heap]
7f1aaf5ac000-7f1aaf763000 r-xp 00000000 fd:01 657569                     /usr/lib64/libc-2.17.so
7f1aaf763000-7f1aaf962000 ---p 001b7000 fd:01 657569                     /usr/lib64/libc-2.17.so
7f1aaf962000-7f1aaf966000 r--p 001b6000 fd:01 657569                     /usr/lib64/libc-2.17.so
7f1aaf966000-7f1aaf968000 rw-p 001ba000 fd:01 657569                     /usr/lib64/libc-2.17.so
7f1aaf968000-7f1aaf96d000 rw-p 00000000 00:00 0 
7f1aaf96d000-7f1aaf983000 r-xp 00000000 fd:01 1704603                    /apps/sylar/lib64/libgcc_s.so.1
7f1aaf983000-7f1aafb83000 ---p 00016000 fd:01 1704603                    /apps/sylar/lib64/libgcc_s.so.1
7f1aafb83000-7f1aafb84000 r--p 00016000 fd:01 1704603                    /apps/sylar/lib64/libgcc_s.so.1
7f1aafb84000-7f1aafb85000 rw-p 00017000 fd:01 1704603                    /apps/sylar/lib64/libgcc_s.so.1
7f1aafb85000-7f1aafc85000 r-xp 00000000 fd:01 657577                     /usr/lib64/libm-2.17.so
7f1aafc85000-7f1aafe85000 ---p 00100000 fd:01 657577                     /usr/lib64/libm-2.17.so
7f1aafe85000-7f1aafe86000 r--p 00100000 fd:01 657577                     /usr/lib64/libm-2.17.so
7f1aafe86000-7f1aafe87000 rw-p 00101000 fd:01 657577                     /usr/lib64/libm-2.17.so
7f1aafe87000-7f1ab0050000 r-xp 00000000 fd:01 1705451                    /apps/sylar/lib64/libstdc++.so.6.0.26
7f1ab0050000-7f1ab024f000 ---p 001c9000 fd:01 1705451                    /apps/sylar/lib64/libstdc++.so.6.0.26
7f1ab024f000-7f1ab025a000 r--p 001c8000 fd:01 1705451                    /apps/sylar/lib64/libstdc++.so.6.0.26
7f1ab025a000-7f1ab025d000 rw-p 001d3000 fd:01 1705451                    /apps/sylar/lib64/libstdc++.so.6.0.26
7f1ab025d000-7f1ab0260000 rw-p 00000000 00:00 0 
7f1ab0260000-7f1ab0280000 r-xp 00000000 fd:01 656965                     /usr/lib64/ld-2.17.so
7f1ab0474000-7f1ab0479000 rw-p 00000000 00:00 0 
7f1ab047e000-7f1ab0480000 rw-p 00000000 00:00 0 
7f1ab0480000-7f1ab0481000 r--p 00020000 fd:01 656965                     /usr/lib64/ld-2.17.so
7f1ab0481000-7f1ab0482000 rw-p 00021000 fd:01 656965                     /usr/lib64/ld-2.17.so
7f1ab0482000-7f1ab0483000 rw-p 00000000 00:00 0 
7fff70c24000-7fff70c45000 rw-p 00000000 00:00 0                          [stack]
7fff70d18000-7fff70d1a000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
[1]    28037 abort      ./a.out

2、void指向有string成员变量的类对象,删除void不能正确析构string成员变量,类的析构函数都不会被调用。谨慎使用void*指向复杂对象,无奈这么用了,删除时记得转回原对象类型指针再删除. 因为delete void * is undefined [-Wdelete-incomplete], 非完全类型。

struct stInfo
{
	int age;
	std::string name;
};
 
int main()
{
	stInfo info;
	info.name = "dandan";
 
	stInfo* p = new stInfo();
	memcpy(p, &info, sizeof(info));
 
    void *ptr = p;
	//...
	delete ptr;   
	return 0;
}  

运行现象:

➜  Test g++ test.cc
alignas.cc: In function ‘int main()’:
alignas.cc:22:9: warning: deleting ‘void*’ is undefined [-Wdelete-incomplete]
   22 |  delete ptr;    
      |         ^~~
➜  Test ./a.out 
➜  Test 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Erice_s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值