C++深浅拷贝

1 篇文章 0 订阅
1 篇文章 0 订阅

我的理解

当结构体中没有指针时,可进行浅拷贝,数据也会从一个结构体拷贝到另一个结构体(两个结构体都存一份数据)。但当结构体中有指针的时候,假如使用使用浅拷贝,会使两个结构体使用的指针都指向同一个内存地址,在析构的时候会造成内存泄漏。

深拷贝:需要对含有指针的结构体,使用“new xxx”申请新的内存空间去存储拷贝的数据
浅拷贝:最简单的可以直接使用 “=”进行赋值,不涉及到手动申请内存空间

项目背景

有两个子模块A,B,他们都需要访问同一份数据,但是这两个模块都会对数据进行clear。
数据模块C,将C* data的地址赋值给A模块,则A模块就能直接访问data的数据地址了。
理论上B也需要使用模块C的数据,但是不能使用同一份数据,需要进行深拷贝,将同样的数据存在两个不同的地址。

假数据

class A;
class B;
struct C{
int m;
};

踩过的坑

同一个内存的模块C的数据(假如结构体如上),同时被模块A,B访问;A删除C.m,B又去访问C.m,此时内存中C的数据m已经被A删除,并不存在了。B访问了不存在的地址,即访问了非法内存,因此会造成内存泄漏导致进程崩溃。

还有一个比较有趣的地方:在实机验证的时候,并不会经常导致进程崩溃;这是因为在实际环境中,不断的通过socket在向模块C的地址写入数据,当A删除了C.m,在B访问C.m之前,socket收到数据又对C.m进行了赋值,因此B也能正常访问C.m了。

伪代码

C* a_c = nullptr;
C* b_c = nullptr; //一定要指定为空,或者在构造函数中初始化为空
C * m_data; //假设有数据

void C::getAData( C *data)
{
if (!a_c)
{
a_c = new C;
}
memcpy ( a_c , m_data , sizeof(a_c);
a_c = data; //将指针a_c的地址内存,赋值给data;data即为A模块里面访问数据的结构体
}

void C::getBData( C *data)
{
if (!a_c)
{
b_c = new C;
}
memcpy ( b_c , m_data , sizeof(b_c);
b_c = data; //将指针b_c的地址内存,赋值给data;B模块通过data,就能访问C模块的数据了
}

特别说明

memcpy ( &a_c , &data , sizeof(a_c),假如带&,就是对地址的拷贝,并不是对地址内数据的拷贝;
若二者都使用 memcpy ( &a_c , &data , sizeof(a_c) , memcpy ( &b_c , &data , sizeof(b_c),则a_c与b_c 以及data 都是共享的同一个内存的地址(即指向同一个内存)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值