内存使用

来源:互联网 发布:用友固定资产登记软件 编辑:程序博客网 时间:2024/04/27 14:44

在做嵌入式开发过程中,内存问题时时提醒着我们,小心小心又小心的使用者有限的内存。

 

内存分配方式:

1、从静态区域分配。内存在程序编译的时候就已经分配好了,这块内存在程序的整个运行期间都存在。例如全局变量、static变量。

2、在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配的运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

3、从堆上分配。也称为动态分配,程序在运行是调用mallocnew申请任意的内存,程序员自己负责在何时使用freedelete释放内存。动态内存的生存周期由程序员自己决定,使用灵活!

 

常见的内存使用错误已经对策

1、内存分配未成功,却使用了它。

新手常犯,没有意识到内存分配会不成功。

常用的解决办法:在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查,如果用malloc或new来申请内存,应该用if(p==NULL)或if(p!=NULL)进行防错处理。

2、内存分配虽然成功,但是尚未初始化就使用。

主要由两个原因:一是没有初始化的观念;二是误以为内存的缺省初始值全为零,导致引用初值错误。内存的初始值到底是什么,我们无法确定,所以,无论用何种方式床数组或指针,都别忘了赋初值。即使是零值,不可省略,不要嫌麻烦。

3、内存分配成功并已经初始化,但是操作越过了内存的边界。

例如在使用数组经常发生下标“多1”或“少1”的操作,特别是在for循环语句中,循环的次数很容易搞错,导致数组操作越界。

4、忘记释放内存,导致内存泄露。

含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存不足,你看不到错误,中有一次程序突然死掉,系统出现提示:内存不足。动态内存的申请与释放必须配对,程序中malloc与free的使用一定要相同,否则肯定有错误。

5、释放了内存却继续使用它。

A 程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。

B 函数的return语句写错了,注意不要返回“栈内存”的指针或引用,因为这些内存在函数结束时被自动销毁了。

C 使用free或delete释放了内存后,没有将指针设置为NULL,导致产生野指针

 

野指针

野指针不是NULL指针,是指向“垃圾”内存的指针,你可能不会用错NULL指针,因为if语句很容易就判断出来,但是野指针是很危险的,if语句对它不起作用。

野指针的成因主要有:

A 指针变量没有被初始化。任何指针变量在创建时都不会被自动初始化为NULL指针,它的默认值是随机的,乱指一气。所以,指针变量在创建的同时应当被初始化,将指针设置为NULL,或者指向合法的内存。

                char *p = NULL;

                char *str = (char *)malloc(100);

B 指针P被free或者delete之后,没有设置为NULL,让人误以为p是个合法的地址。

 

补充一点,熟悉C++的朋友可能会问,有了malloc/free为什么还要new/delete?下面是小弟平时学习过程中遇到的一些答案

前者是C或C++的标准库函数,而后者是C++的运算符,他们都可以用于申请动态内存和释放内存。New和delete不是函数而是运算符。

对于非内部数据类型的对象而言,光用malloc和free无法满足动态对象的要求,对象在创建爱你的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数,由于malloc和free是函数而不是运算符,不在编译器的控制范围之内,不能够把执行构造函数和析构函数的任务强加于他。

既然new和delete的功能完全覆盖了malloc和free函数,为什么C++不把malloc和free淘汰呢?因为C++程序经常要调用C函数,而C程序只能使用malloc和free函数。