牛骨文教育服务平台(让学习变的简单)
博文笔记

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

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

我们写了一个核心函数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次。

 

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

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。