C++智能指针

1. 前言

    这依然是面试的一大考点。(好吧,怎么又是面试呢?我说就不能说点对技术有用的东西吗?)

    不能,开玩笑的,其实智能指针真的很方便了C++开发人员。

    好吧,说到智能指针,还是先从c++常见的内存问题说起吧。    


2. 内存问题

    (1) 缓冲区溢出问题

    说的简单一点,就是你申明了一个64长度的数组,却要访问并修改第65位,虽然有时候是不会出现问题,但是实际上,这个地址根本不知道里面放着什么东西,可能是函数的返回值?可能是某些重要的数据?可能是下面需要用到的数组?总之,这种情况造成的后果是不可估量的。

    (2) 空悬指针/野指针

    空悬指针/野指针是什么东西呢?举个简单的例子,比如有两个指针,都指向堆上相同的一个对象Object,然后这个两个指针分别位于不同的线程中,这样的话第一个线程肯定不知道第二个线程做了什么?第二个线程也不知道第一个线程有没有对该堆上数据做什么修改?

    假如现在p1释放了这个堆上的内存,那么p2就成了野指针/空悬指针,因为它所指向的东西是不存在的。样例图如下:


p1,p2同时指向堆中Object对象


p1释放了资源,p2就成了空悬指针/野指针

    这就是空悬指针/野指针

    (3) 重复释放

    这个问题和上面那个很像,只是当p2指向的东西被p1释放的时候,p2再去释放一次。

    (4) 内存泄漏

    这个问题是最常见的问题,当然,也不怎么好解决。但并不是那么严重的问题,毕竟比起缓冲区溢出,重复释放这种会导致系统奔溃的问题而言,内存泄漏其实并不算大问题,但也是一个常见的问题,毕竟随着使用的时间的增加,内存的增加也成线性,一定时间时候服务器的内存就会被占满,这不符合使用服务器的使用。

    下面举个比较常见的例子:

char* IntToString(int n)
{
    char *ch = new char[33];
    int flag = 1,num = 0;

    if(n < 0 )
    {
        flag = 0;
        num++;
        n = -n;
    }

    while(n)
    {
        ch[num++] = n%10 + '0';
        n = n/10;
    }

    for(int i=0;i<num/2 && flag;i++)
        swap(ch[i],ch[num-i-flag]);

    for(int i=1;i<=num/2 && !flag;i++)
        swap(ch[i],ch[num-i]);

    if(!flag) ch[0] = '-';

    ch[num] = '\0';
    return ch;
}

    上面的代码是一个整数变成字符串的例子,很容易理解,乍一看,觉得好像并不存在BUG,这和内存泄露有什么关系,但是仔细想一想,如果有那个客户端的小伙伴不小心使用了以下的代码:    

cout << IntToString(100) << endl;

    是不是就出事了,咦,创建的ch指针里面的内存去哪了?没错,这个时候无论怎么做,都没法释放你之前申请的内存。(这里可以使用string模板类来解决或者使用智能指针了来解决。)    

    (5) 不匹配的new[] / delete

    这个问题,感觉没什么意义!在《Linux多线程服务器编程 使用moduo C++网络库》中说道,尽量不要自己使用delete,delete应该是交给资源管理者而不是申请资源的人。当然,也不是一定不能用。那会出现什么问题呢?我先简单说一下,就是new[]的时候你分配的是一个数组,这个数组包含了数组的大小以及数组里面的元素空间,使用delete的时候,delete执行的步骤是释放掉数组的大小以及数组的第一个元素,如果你数组原来存放的是类似String这样的东西,除了第一个,后面的析构函数是不会调用的,也就是你申请的内存统统都不会回收,这实际上也是一种内存泄漏的问题。

    (6) 内存碎片<

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值