第7章:内存管理

末鹿安然 提交于 2019-12-02 14:50:34

一、内存分配方式

1、静态区域分配:在程序编译期间就已经分配好的,例如全局变量、static变量

2、在栈上分配:函数内部的局部变量

3、从堆上分配(动态分配):通过malloc或者new开辟的空间

 

二、常见的内存错误及其对策

1、内存错误----->解决措施

  a、内存未开辟成功,却使用它----->应该用if(NULL == p)或者if(NULL != p)来判断是否开辟成功

  b、内存开辟成功,但未初始化就使用----->在内存开辟成功的时候就赋初值

  c、内存分配成功也初始化,但操作越过了内存的边界(内存越界):----->

  d、忘记释放内存)内存泄漏:----->malloc与free的使用次数一定要相同(new与delete一样,使用次数要相同)

  e、释放了内存却继续使用它(野指针):----->释放内存后紧接着将指针设置成null;不要返回栈内存上开辟的空间的地址

总结:

1、用malloc和new申请内存后,应立即检查指针值是否为NULL

2、不要忘记为数组和动态内存赋初值

3、避免数组或指针的下标越界

4、动态内存的申请与释放必须配对,防止内存泄漏

5、用free或delete释放内存之后,立即将指针设置为NULL

 

三、指针与数组相比

1、同时指向字符串的时候:数组可以改变任意位置的内容,而指针不可以,因为其指向的空间是一个字符串,字符串的内容不能进行修改

2、不能对数组名进行直接复制与比较(若想将数组内容赋给指针,只能用strcpy,比较也只能用strcmp)

3、当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针,其余的时候均是数组

 

四、指针参数传递内存

1、指针作为实参,传递的是指向空间的地址,如果该指针为空,则传递失效,无论形参怎么改变对实参都无任何作用

2、形参可以用一个二级指针去接收实参的一级指针的地址(可以直接改变实参指针的指向空间)

3、不要用return语句返回栈内存指针

 

五、free与delete

只是把指针所指向的空间释放掉,但指向该空间的指针还在,空间释放后该指针会变成野指针。

 

六、动态内存释放

1、指针消亡了但是动态开辟的空间并没有释放---->在指针消亡之前释放掉该空间

2、内存被释放了,并不表示指针会消亡或者成了NULL指针----->及时把指针指向空

 

七、杜绝野指针

野指针的形成原因:

  a、指针变量没有初始化

  b、指向空间被释放后没有及时置为NULL

  c、指针操作越过了变量的作用域

 

八、malloc与new

这一部分是我自己总结的(并非书本上的知识):

   (1)malloc和free是函数,new和delete是操作符

   (2)malloc申请空间不会初始化,new可以初始化

   (3)malloc申请空间是,需要手动计算空间大小并传递,new只需要在其后跟上空间的类型即可

   (4)malloc的返回值为void*,在使用时必须进行强转,new不需要,因为new后跟的是空间的类型

   (5)malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常

   (6)申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造/析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

   (7)new/delete比malloc/free的效率稍微低一点,因为new/delete底层封装了malloc/free

1、new/delete、mallloc/free必须配对使用

2、new不是库函数,mallloc是库函数.

 

九、内存耗尽怎么办?

1、判断指针是否为NULL,如果是则马上用return语句终止本函数

2、判断指针是否为NULL,如果是则马上用exit(1)终止整个程序的运行

3、为new和malloc设置异常处理函数

 

十、malloc/free的使用要点

1、malloc的返回值是void*,所以要进行显示的类型转换

2、malloc只关心要开辟空间的字节数

 

十一、new/delete的使用要点

1、new在创建动态对象的时候同时完成了初始化工作

2、如果用new创建数组,那么只能使用对象的无参构造函数

3、在使用delete释放对象数组时,留意不要丢弃了符号‘[]’

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!