避免内存泄露的方法

转载 2015年07月10日 16:46:26

1、 问题阐述

      一个大型的C++程序中最容易出现,也是最头疼的一个问题就是内存泄露,即忘记释放已经申请的内存,造成程序占用的内存不断上升,系统性能不断下降,甚至造成内存耗尽而导致程序崩溃。在Java中提供自动垃圾回收机制,程序在何时的时机将回收内存,C++语言一直没有将这种机制作为语言的内部机制,但是它也提供了足够的灵活机制,使开发人员有效地避免内存泄露。

2、 内部封装

      可以将分配和释放的过程封装到一个类中,即在构造的时候申请内存,析构的时候释放内存,从而保证没有内存泄露。下面是一个简单的封装类。

#include <iostream>
#include 
<cstring>
using namespace std;
class AutoNewDel
{
private:
    
char* m_szBuf;
    unsigned 
int m_nSize;
public:
    AutoNewDel(unsigned 
int n=1)
    
{
        m_szBuf
=new char[n];
        m_nSize
=n;
    }
;
    
~AutoNewDel()
    
{
        
if(m_szBuf!=NULL)    //提供安全机制
        {
            delete[] m_szBuf;    
//删除字符数组
            m_szBuf=NULL;    //防止出现野指针
        }

    }
;
    
char* GetBuf()
    
{
        
return m_szBuf;
    }
;
}
;
void fun()
{
    AutoNewDel tmpObj(
100);
    
char* p= tmpObj.GetBuf();
    strcpy(p,
"one world, one dream");
    cout
<<p<<endl;
}

int main()
{
    fun();
    cout
<<"exit main"<<endl;
    
return 0;
}

      在这个例子中,封装了char类型的内存分配和删除,当声明对象tmpObj时,即可获得相应的内存,而且这个内存再tmpObj对象的作用域推出时自动释放,不需要开发人员显示的调用delete来释放了,避免了由于忘记释放内存而引起的内存泄露错误。
      本例给出了一个最基本的思路,但是还是存在很多问题的,比如复制构造函数和复制的问题。下面将演示这个例子的不足,修改函数fun(),增加一个赋值语句,如下:
void fun()
{
    AutoNewDel tmpObj(
100);
    AutoNewDel tmpObj2
=tmpObj;//这里是增加的语句
    char* p= tmpObj.GetBuf();
    strcpy(p,
"one world, one dream");
    cout
<<p<<endl;
}
      在这个类中并没有实现复制构造函数,因此编译器自动构造一个默认的复制构造函数,执行位复制操作,即将对象tmpObj的内容逐字地复制到对象tmpObj2中,两个对象中的m_szBuf指向同一块内存,当对象销毁时,m_szBuf会被销毁两次,从而造成程序错误(本博客还有一篇随笔说明相关的内容,随笔地址为:C++ primer plus第十一章 使用类的程序。简单的解决办法就是禁止复制构造函数,在类中声明复制构造函数为私有。但是这样治标不治本,它限制类的功能实现。可以通过一个引用一个计数的方法,即避免了对同一块内存的多次删除,也允许复制构造函数。
      
      引用的计数的原理是这样的,就是对要使用的内存维护一个计数器,记录当前有多少指针指向这块内存。当有指针指向这块内存时,计数器加1;反之,当指向这块内存指针销毁时,计数器减1。当这块内存的计数器为0时,才允许删除这块内存。可以在类的构造函数和析构函数中分别完成加1和减1的操作。代码如下:
#include <iostream>
#include 
<cstring>
using namespace std;
class AutoNewDel
{
// Attribute
private:
    
char* m_szBuf;
    unsigned 
int m_nSize;
    
int * m_count;    //新增加的语句
public:
    AutoNewDel(unsigned 
int n=1)//在构造函数中申请内存
    {
        m_szBuf
=new char[n];
        m_nSize
=n;
        
//新增加的语句
        m_count=new int;
        
*m_count=1;
        cout
<<"count is : "<<*m_count<<endl;
    }
;
    
//新增加的复制构造函数
    AutoNewDel(const AutoNewDel & s)
    
{
        m_nSize
=s.m_nSize;
        m_szBuf
=s.m_szBuf;
        m_count
=s.m_count;
        (
*m_count)++;
        cout
<<"count is : "<<*m_count<<endl;
    }

    
~AutoNewDel()
    
{
        (
*m_count)--;
        cout
<<"count is : "<<*m_count<<endl;//新增加的两条语句
        
        
if(*m_count==0)
        
{
            cout
<<"buf is deleted"<<endl;
            
if(m_szBuf!=NULL)    //提供安全机制
            {
                delete[] m_szBuf;    
//删除字符数组
                m_szBuf=NULL;    //防止出现野指针
                if(m_count!=NULL)
                
{
                    delete m_count;
                    m_count
=NULL;
                }

            }

        }

    }
;
    
char* GetBuf()
    
{
        
return m_szBuf;
    }
;
}
;
void fun()
{
    AutoNewDel tmpObj(
100);
    
char* p= tmpObj.GetBuf();
    strcpy(p,
"one world, one dream");
    cout
<<p<<endl;

    AutoNewDel tmpObj2
=tmpObj;
    cout
<<"tmpObj2.m_szBuf = "<<tmpObj2.GetBuf()<<endl;
}

int main()
{
    fun();
    cout
<<"exit main"<<endl;
    
return 0;
}

程序输出结果如下:


想要获得更多内容,可点击:《Visuanl C++代码参考与技巧大全》学习笔记——索引随笔

Android内存优化方案和内存泄露检测分析方法

常见内存泄露及优化方案1、单例错误写法:public class AppSettings { private static AppSettings sInstance; private ...
  • iromkoear
  • iromkoear
  • 2017年04月26日 20:54
  • 474

Java 内存泄露以及避免方法

Java代码   内存泄露:      是指在程序运行过程中会不断的分配内存空间,那些不再使用的内存空间应该即时回收它们,从而保证可以保证系统可以再次使用这些内存。如果存在无用的内存没...
  • jay1110C
  • jay1110C
  • 2016年08月26日 09:11
  • 312

避免内存泄露的方法

1、 问题阐述       一个大型的C++程序中最容易出现,也是最头疼的一个问题就是内存泄露,即忘记释放已经申请的内存,造成程序占用的内存不断上升,系统性能不断下降,甚至造成内存耗尽而导致程序崩溃...
  • chenxun2009
  • chenxun2009
  • 2014年04月29日 16:30
  • 912

详解java内存泄露和如何避免内存泄漏

源地址:http://www.xttblog.com/?p=518 一直以来java都占据着语言排行榜的头把交椅。这是与java的设计密不可分的,其中最令大家喜欢的不是面向对象,而是垃圾回收机制。你...
  • xidiancyp
  • xidiancyp
  • 2016年05月15日 18:10
  • 4249

Java中关于内存泄漏出现的原因以及如何避免内存泄漏(超详细版汇总上)

Android 内存泄漏总结内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所持有却不...
  • wtt945482445
  • wtt945482445
  • 2016年09月09日 08:58
  • 9383

4类 JavaScript 内存泄漏及如何避免

本文将探索常见的客户端 JavaScript 内存泄漏,以及如何使用 Chrome 开发工具发现问题。 简介 内存泄漏是每个开发者最终都要面对的问题,它是许多问题的根源:反应迟缓,崩溃,高...
  • u012125579
  • u012125579
  • 2016年05月28日 14:14
  • 1182

Android中内存泄露与如何有效避免OOM总结

Android系统为每个应用程序分配的内存有限,当一个应用中产生的内存泄漏比较多时,就难免会导致应用所需要的内存超过这个系统分配的内存限额,这就造成了内存溢出而导致应用Crash。内存泄露的危害:只有...
  • gjnm820
  • gjnm820
  • 2016年06月03日 15:09
  • 4299

4种JavaScript的内存泄露及避免方法

这篇文章里面我们会讨论客户侧javascript代码中的常见种类的内存泄漏。也会学习如何用Chrome Development Tools来定位这些问题。继续阅读吧! 介绍 内存泄漏是每个...
  • web_lc
  • web_lc
  • 2017年06月08日 15:31
  • 1309

防止Java内存泄露的一些小细节

今天面试时面试官问了Java内存泄露的一些处理方式,我竟然一时答不上来,回家之后百度查询了一下,结果如下: 1、尽早释放无用对象的引用。特别是大对象和集合对象,通过置为NULL,暗示垃圾收集器来...
  • knighttools
  • knighttools
  • 2015年03月25日 23:51
  • 1710

如何避免内存泄漏

如何避免内存泄漏
  • duan19920101
  • duan19920101
  • 2016年03月27日 22:33
  • 955
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:避免内存泄露的方法
举报原因:
原因补充:

(最多只允许输入30个字)