您的位置:首页 > 编程语言 > C语言/C++

【C/C++】C语言中一些容易被人忽略的东西 之一 【内存的分配与释放】

2013-02-05 13:02 330 查看


转载请注明出处

由于阅历有限,篇幅不周之处还望指出,谢谢[X]和[X*]...[*X]标注的为错误的

题记:

最近在看一本C语言书,感觉挺不错的,但书中有些错误。同时又发现了一些容易被自己或者大家都容易忽略掉的东西,于是记下来跟大家分享下,文中内容如有错误还望大家一定帮忙指出下,谢谢!

一、内存的分配与释放

学过C语言的都知道,内存分配了用完之后是要释放的,都是到malloc和calloc函数以及free函数。那么分配了内存之后是不是真就free(pointer)这么简单呢?

这里提及要注意的地方,参数pointer必须是调用malloc或calloc函数后返回的指针,而给free函数传递其它的值可能会造成死机或者结果是灾难性的。重点是指针的值,而不是用来申请动态内存的指针本身。

可以看下代码,

[X*]假如先前有void * p =malloc(sizeof(double)*6);

也有double * dp=(double *)(malloc(sizeof(double)*6));

那么此刻如果free(dp)就会出现不可预知的错误,free(p)是正确的,

若又p=dp,(或者p=(void *)dp),然后free(p)也是正确的

所谓灾难性的无非就是释放内存中出现把不该释放的东西给释放了,然后引起了一些问题。

那么,怎么来验证free(dp)就是错误的呢?这也许是个内存泄露的问题,呵呵。

可以试下这样一段代码:

for(;;)

{

double * p=malloc(sizeof(double)*6);

free(p);

}

然后,看看你的内存是否超支(不够)了?

[*X]

正确的说法:

假如先前有double * p =malloc(sizeof(double)*6);

那么此刻如果free(p+1)就会出现不可预知的错误,free(p)是正确的,

原因就是分配内存函数对该地址值及对应的内存块有记忆,而p+1不在记忆列表里,所以free(p+1)会引发灾难性错误

可以试下这样一段代码:

for(;;)

{

double * p=malloc(sizeof(double)*6);

free(p+1);

}

再看看realloc函数,它可以用来重新分配经m,c,r三者分配的内存。那么重新分配真的是给一块新的地址嘛?

事实上并不是这样的,r有两个参数,一个是指针,引用之前分配的内存,重新分配的内存是在原来基础之上,大小则由第二个参数决定。也就是说,如果你家庭总收入6000元,总管(通常是母的)给儿子分配了1000元的零花钱,现在由于一些"不可抗力"因素,要重新分配money,那么,传递参数realloc(1000元的地址,newsize),newsize<=1000U。而本质上是将儿子手中的money根据newsize抽走一部分,然后剩下的会做一些处理。

动态内存分配的一些原则:

1、需要时分配,用完就释放,特别是堆上的(资源很有限)。

2、避免分配大量小块内存,因为堆上内存的分配由于有系统开销,所以分配许多的小内存比分配几块大内存开销要大,而已不便于释放和管理。

3、编程的时候始终把用户有限的内存放在心上,分配了就要考虑在哪里释放。

4、循环中分配内存一定要小心翼翼

5、释放内存之前,确保不会无意中覆盖堆上分配的内存地址,否则会出现内存泄露
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: