避免内存泄漏

前面我们讲过,分配了一个内存块但忘记了释放它这是一个严重的错误,这样的内存块要等到程序执行结束时才会被释放掉(不懂的话就看栈的相关介绍)。

如果程序运行很长时间(例如在服务器上,注意不是所有的操作系统都像windows一样每天都要重启)并且在不停地申请新内存块,忘记释放那些已经不再有用的老内存块将迟早会把内存消耗殆尽,直接导致后面的new操作无法执行甚至是崩溃。

这样的编程漏洞我们称之为内存泄漏(memory leak)。

new语句所返回的地址是访问这个内存块的唯一线索,同时也是delete语句用来把这个内存块归还给内存池的唯一线索。

看下这个例子:

int *x;
x = new int[1000];
delete[] x;
x = NULL;

这意味着如果这个地址值(保存在x里)丢失了,就会发生内存泄漏问题。

地址值会因为很多原因而丢失

第一种情况,因为一个地址变量被无意中改写,例如:

int *x;
x = new int[3000];
x = new int[4000];
delete[] x;
x = NULL;

这样上面那个地址就没了,就是造成内存泄漏。

第二种情况,用来保存内存块地址的指针变量作用域问题,例如:

void foo()
{
    My Class *x;
    x = new MyClass();
}

当foo函数结束时,指针变量x将超出它的作用域,这意味着它将不复存在,它的值当然就会丢失。

有两种方法可以解决解决该漏洞

1. 在return语句之前的某个地方插入一条delete x语句,如:

void foo()
{
    MyClass *x;
    x = new MyClass();
    delete x;
    x = NULL;
    return 0;
}

如果没有return就在结束之前插入,一个意思。

2. 让函数把内存块的地址返回给它的调用者,如:

void foo()
{
    MyClass *x;
    x = new MyClass();

    return x;

内存作用域

变量都有一个作用域:规定了它可以在程序的哪些部分使用。

这个作用域通常就是对它们做出声明和定义的函数的函数体,如main函数或某个子函数。

如果被定义在任何一个函数的外部,变量将拥有全局作用域,这意味它们可以在整个程序中的所有函数里使用。

不过应该避免使用全局变量,因为它们往往会让代码变得难以调试和容易出错。

动态内存不存在作用域的问题,一旦被分配,内存块可以在程序的任何地方使用。

因为动态内存没有作用域,所以必须由程序员来跟踪它们的使用情况,并在不再需要用到它们的时候把它们及时归还给系统。

这里需要特别注意的是,虽然动态分配的内存块没有作用域,但用来保存其地址的指针变量是受作用域影响的。就是上面讲的上面的内存泄漏问题。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值