内存使用问题应该注意这五点
来源:互联网 发布:最短路径算法 最优 编辑:程序博客网 时间:2024/05/21 10:00
* 在程序员的世界里,“内存”这个词被比作“雷区”,因为很多时候程序代码编译能通过,但是结果却不是我们想要的,或者编译的时候中断,这时候,我们便开始绞尽脑汁地调试,想尽各种办法,经过七七四十九天之后,突然眼前一亮,oh my god!居然是一个语句中内存使用错误。所以,与其花费那么多时间调试,还不如好好想想如何尽量少出现这种错误。下面,我总结了在内存使用时的常见错误。*
1.对NULL指针进行解引用操作
内存使用最常见的错误就是忘记检查所请求的内存分配是否成功,此外,在函数实现的时候,如果有指针变量作为形参,没有对参数进行NULL判断。下面给出几点建议:
(1)使用malloc()的时候,一定要使用if()语句进行判断,如code1所示。当然,你也可以按照自己的方式进行指针检查。
//code1: int *ptr = (int *)(10 * sizeof(int)); if (NULL == ptr) exit(EXIT_FAILURE);
(2)在函数的入口处,若形参为指针变量,则用assert()检查指针是否为空,形如assert(NULL!=ptr);
(3)定义一个指针变量时,一定要将其初始化,可以为某个值的地址,可以为NULL。
2.对内存的使用越界
对内存的使用越界,比如你申请了一块空间,每次使用一定的字节,若算法出错,导致使用了你所申请的空间的下一个空间。这个时候,这块空间有可能是不可访问的,对于这种情况你还是很幸运的,至少编译器会有错误提示。然而,如果这块空间正好存放了其他有用的数据,那么你的做法将会改变这块空间的内容,这个问题是非常让人头疼的,因为在大多数情况下,编译器是不会报错的,而且还能显示结果,只是结果很可能不是你想要的。来看code2,先自己想想结果是什么?
//code2#include<stdio.h>#include<stdlib.h>int main(){ int i = 0; int arr[10]; for (i = 0; i <= 12; i++) { arr[i] = 0; printf("%d ", arr[i]); } system("pause"); return 0;}
来看结果
简直让人大吃一惊,出现了死循环。我们知道,栈是向下增长的,而数组元素的地址是依次升高的,在vs2013编译器下,变量i和数组arr中间空了2个字节的大小(注意,在其他编译器下很可能不是两个字节,比如vc6.0或者gcc)。当arr[9]被赋值为0时,循环会继续进行,此时,(arr+10)、(arr+11)(arr+12)这三快内存都被赋值为0,但是,注意到arr+12这块内存空间正好是变量i的空间,当我们执行(arr+12)=0;的时候,变量i又从新变成了0。这样,明白了为什么会死循环了吧。
3.释放并非动态分配的内存
在第2中情况下,假如这块空间是使用malloc()在堆上开辟的,当你想要用free()释放的时候,程序便会中断(我的环境是在Windows平台的vs2013下)。如code2所示。
//code3#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){ char *p = "hello world!"; char *ptr = NULL; int len = strlen(p); ptr = (char *)malloc(len*sizeof(char)); if (NULL == ptr) exit(0); strcpy(ptr, p); printf("%s\n", ptr); system("pause"); return 0;}
结果的确是我们想要的,可是,这里出现什么问题了呢?注意到代码中没有用free()释放,这时我们在printf(“%s\n”, ptr);语句后面加上free(ptr)会发生什么了?如下图所示:
当我们调试的时候,会发现程序终止在free(ptr)处,因为strlen()计算长度的时候并没有把‘\0’加进去,但是在拷贝的时候,把‘\0’也放到了ptr所指向的内存中,但是很明显空间不够用,这时‘\0’放在了我们申请的空间的下一个字节的地方。当我们使用free()释放的时候,企图把不是动态分配的空间也给释放掉,这时非法的,所以程序发生了中断。
4.释放动态分配内存的一部分
在使用free()时,传递给free函数的指针必须是一个从malloc、calloc或realloc函数返回的指针,并且不能企图释放这块内存的一部分。比如free(ptr+2),其中ptr是由malloc分配的内存。但是,relloc函数可以缩小一块动态分配的内存,可是有效地释放它尾部的部分内存。
5.使用了已被释放的内存
有时候,当我们的代码量非常大的时候,会容易犯这样的错误,在free掉某个内存之后,我们依然对其进行使用。这种情况下,在vs2013软件中会出现如下图所示的中断。
- 内存使用问题应该注意这五点
- vector 容器使用时应该注意的内存分配问题
- vector 容器使用时应该注意的内存分配问题
- 避免常见的内存错误应注意的五点
- 使用静态数组应该注意的问题
- 使用静态数组应该注意的问题
- matlab使用reshape应该注意的问题
- matlab使用reshape应该注意的问题
- ssh 使用时应该注意的问题
- 使用memcache应该注意的问题
- matlab使用reshape应该注意的问题
- 使用LayoutInflater应该注意的问题
- 使用butterknife应该注意的问题
- C++指针及内存申请时应该注意问题
- 使用梅花雨日历控件应该注意的问题
- 对于使用xml配置文档时应该注意的问题
- [原创]web application中使用Profile应该注意的问题
- 喜欢使用VMware的.NET程序员应该注意的问题
- 二叉树前序遍历的迭代实现
- 使用Fragment懒加载的一种方式
- linux下PHP 环境搭建
- 不懂技术的人不要对懂技术的人说这很容易实现
- 10.26
- 内存使用问题应该注意这五点
- 机器学习&深度学习资料(Chapter 15 )
- govmomi (vSphere SDK for Go), govc CLI & Kubernetes on vSphere
- 11月12日广州源创会火热报名中
- DeepCare 2017校园招聘
- bee(github.com/beego/bee)源码分析
- NIO(2) Channel之间数据传输
- 互联网上市公司招聘:推荐引擎Leader
- RHEL6解决无法使用YUM源问题