如何避免内存频繁地申请与释放

 
如何避免内存频繁地申请与释放
 
动态内存申请与释放在很大程度上影响着程序的运行效率,如果频繁地进行内存申请与释放,程序极可能出错,同时给程序造成巨大的负担,因此尽量避免这样的操作是很有意义的。本文讨论一下这个问题。
 
问题描述:

我们写了一个核心函数fun,它的大致形式如下:

void fun(int len, datatype/*, 其他参数*/ )
{
    
//……

    datatype *tmp = new datatype[len];
    
//……

    delete [] tmp;
    
//……

}

现在要在另一个函数fun_call中,频繁地调用此函数,它的大致形式如下:

void fun_call(int len, datatype/*, …*/ )
{
    
//……


    
for(int i=0; i<10000++i)
    
{
    
//    ……

        fun(len/*, …*/);
    
//    ……

    }


    
//……
}

每调用一次 fun_call,就要进行10000次(概数,只是打个比方)地内存申请与释放,我们的目的是将这10000次的内存申请与释放改进为只进行1次。

 

解决方法:

大体而言,避免内存频繁申请与释放有如下方法:

 

1、静态申请

如果能够预知所要申请的内存大小,可以用静态申请的方法,直接给一块足够大的数组,即在函数fun 中,用datatype tmp[MAX_SIZE]   来代替 操作。但这样做存在如缺点:要估计程序中申请内存的大小,有时是难以办到的,就算能够估计到申请的内存大小,当我们程序中申请内存的大小变化范围特别大时(如1bit~1M),这时如果只须申请1bit的空间,而实际上却用了1M的空间(虽然在栈上),我觉得这样不妥。

 

2、用半自动的内存管理方式

重载 ,一次调用系统提供的new申请大块内存,以后的申请就从这块内存中进行分割,不再调用系统的new。这样做可行,效率有待研究。

 

3、用函数模板

将核心函数fun改成如下形式:

template < int size >  
void fun(datatype
/*, …*/
)
{
    
//……


    datatype tmp[size];

    
//……
}

这样做之后,将我们要申请的内存大小作为模板参数传入核心函数 中。它同第1种方法静态申请差不多,但它能缓解1中的内存浪费的缺点,相当于方法1中的MAX_SIZE不是固定的数,而是可变的size。在fun的调用函数fun_call中,调用的形式变为了fun<size>()了,而且模板参数size必须是常的。

 

4、用函数重载

核心函数fun将变为两种形式:

void fun(datatype *media, int len, datatype/*, …*/ )
{
    
//……

    datatype *tmp = media;
    
//……

}
void fun(int len, datatype/*, …*/ )
{
    datatype 
*tmp = new
 datatype[len];
    fun(tmp, len
/*, …*/
);
    delete [] tmp;
}


然后在调用函数fun_call中,就调用上述第1种定义,其函数形式大致变为:

void fun_call(int len, datatype/*, …*/ )
{
    
//……

    Datatype *tmp = new datatype[len]
    
for(int i=0; i<10000++
i)
    
{
    
//    ……

        fun(len, tmp/*, ……*/);
    
//    ……

    }

    Delete [] tmp;
    
//……
}

这样一来,10000次的内存申请释放变为了1次。

 

总结:解决方法还有很多,比如使用全局变量,由于全局变量具有诸多不利因素,因此,本文不考虑全局变量。以上只是一些针对内存频繁动态申请和释放的解决思路,抛砖引玉,希望高手指点。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值