第十六章 内存管理(1)====高质量程序设计指南C/C++编程
来源:互联网 发布:灯光设计软件 编辑:程序博客网 时间:2024/06/09 14:13
内存分配方式:
1.从静态存储区分配,内存在程序编译的时候就已经分配好了(即已经编址),这些内存在程序的整个运行期间都存在,如全局变量,static变量等。
2.在堆栈上分配,在函数执行期间,函数内部变量(包括形参)的存储单元都创建在堆栈上,函数结束这些存储单元自动释放,堆栈清退。堆栈内存分配运算内置于处理器的指令集中,效率很高,并且一般不存在失败的危险,但是分配的内存容量有限,可能出现堆栈溢出。
3.从堆(heap)或自由存储空间上分配,即动态内存分配,程序在运行期间,用malloc()或者new申请任意数量的内存,程序员自己掌握释放内存的恰当时机(使用free()或delete),动态内存的生存期由程序员决定,使用灵活、
常见的内存错误:
1.内存尚未分配成功,却使用了。 检查指针是否为空
2.内存分配成功,但是尚未初始化就使用它 任何的分配需要初始化
3.内存分配成功已经初始化,但是访问越过了内存的边界。 如数据的越界访问
4.忘记释放内存或者只是释放了一部分的内存,导致内存泄露。 malloc() free() new delete 使用必须配对
5.释放了内存却还在使用。 注意将已经释放的内存设置为NULL,防止产生野指针。 多次释放同一块内存出现错误。 double free
几点规则:
1.用malloc()或者new申请内存之后,应该立即检查指针值是否为NULL或者进行异常处理,以防止使用值为NULL的指针。
2.不要忘记初始化指针,数组和动态内存,防止将未初始化的内存作为右值使用。
3.避免数组下标访问越界。
4.动态内存的分配和释放必须配对,防止内存泄露。
5.释放内存后应该立即把指针设置成NULL,防止野指针。
指针参数如何传递内存:
1.指针作为参数进行内存的分配,传递指针的指针,或者传递指针的引用。因为实参是拷贝一份传递给形参。
void getmemory(char** p,int num){ *p=(char*)malloc(sizeof(char)*num);}
void getmemory(char*& p,int num){ p=new char;}
2.用函数返回值传递来申请内存
char* getmemory(int num){ char* p=NULL; p=(char*)malloc(num*sizeof(char)); return p;}
3.注意不可以返回局部变量的地址
char* getmemory(int num)
{ char* p="hello world"; return p;}
char* getmemory(){ char p[]="hello world"; return p;}第一种 返回常量存储区的地址OK 第二种错误!!
内存释放:
#include <iostream>#include<cstdio>#include<cstdlib>using namespace std;int main(){ int* p=new int(5); if(p==NULL) throw 1; cout<<p<<endl; delete p; cout<<p<<endl; return 0;}
指针被释放后其指向的地址内人不变,(不等于NULL),但是该地址对应的内存是垃圾------>p成了一个野指针。 所以必须进行设置成NULL
经典:指针消亡了,并不代表它所指的内存会被自动释放 AND 内存被释放了,并不表示指针会消亡或者成了NULL。
野指针:
1.未初始化指针变量,任何指针在初始化时不会自动成为NULL指针,它会乱指一气,所以指针变量创建的同时应该初始化,或者设置成NULL。
2,.指针p被释放后,未设置为NULL。
3.指针变量超越了变量的作用范围。
class A{public: void func(void){cout<<"A::func"<<endl;} ~A(){cout<<"~A()"<<endl;}};int main(){ A* p=NULL; { A a; p=&a;//注意a的生命期 } p->func();//p是野指针 return 0;}上述代码: 根本原因是a虽然退栈,但是仅仅是调用了析构函数,并没有清除a的内存(a的内存仍然在函数堆栈上),所以结果没有错。
MALLOC FREE AND NEW DELETE
maloc,free为C语言的库函数,而不是运算符。 new delete是运算符而不是库函数
用malloc,free函数进行对象的动态内存管理,不能调用构造函数和析构函数。必须程序员自己写函数来完成初始化和清除的工作。
new.delete会自动的调用构造和析构函数来进行调用。
某些情况下,malloc/free效率更高。用户可以自定义类重载 new/delete实现个性的内存分配和释放策略。
注意:如果使用free()来释放new创建的对象,那么该对象可能会无法执行析构函数而导致程序出错, C++并不保证new的底层会用malloc(),而且在一些实现中,malloc和new使用不同的堆,同样,用delete释放malloc申请的动态内存,理论是程序不会出错,但是该程序的可读性会很差。
p==NULL free多次都没事,但是p!=NULL,多次释放会出现错误
- 第十六章 内存管理(1)====高质量程序设计指南C/C++编程
- 第十六章 内存管理 ===高质量C/C++编程指南
- 高质量C++/C编程指南 -- 第7章 内存管理 (1)
- 高质量C++/C编程指南 -- 第7章 内存管理 (1)
- 高质量C++/C编程指南 -- 第7章 内存管理 (1)
- 高质量C++/C编程指南 -- 内存管理之一
- 高质量C++/C编程指南 -- 内存管理之二
- 高质量 C++/C 编程指南 林锐 摘要 内存管理
- 内存管理:高质量C++/C编程指南
- 《高质量程序设计指南——C/C++》第16章 内存管理
- 高质量C++/C编程指南 -- 第7章 内存管理 (2)
- 高质量C++/C编程指南 -- 第7章 内存管理 (2)
- 高质量C++/C编程指南 -- 第7章 内存管理
- 高质量C++/C编程指南 -- 第7章 内存管理
- 读书笔记-高质量C++/C编程指南-第7章 内存管理
- 高质量C++/C编程指南 -- 第7章 内存管理
- 高质量C++/C编程指南 -- 第7章 内存管理
- 高质量C++/C编程指南 -- 第7章 内存管理 P1
- Linux下编译安装PCRE库
- 自定义ViewGroup实现垂直滑屏
- Linux串口编程_termios
- Scramble String -- leetcode
- 欢迎使用CSDN-markdown编辑器
- 第十六章 内存管理(1)====高质量程序设计指南C/C++编程
- zoj 1648 Grandpa's Estate(判断线段是否相交(不考虑端点相交))
- ADB操作常见问题汇总
- 关于react native运用的简单总结
- mysql数据备份导入导出详解
- 编程之美8:链表常见面试笔试题集合
- NuGet来管理你的包——成绩登统系统
- 组合测试法中的全对偶测试法
- 字符串 Substring with Concatenation of All Words