标签:
一.malloc函数(memory allocation) 中文名:动态内存分配
原型:extern void *malloc(unsigned int num_bytes);
说明:分配长度为num_bytes字节的内存块,分配成功,则返回指向该内存块的指针。否则指向NULL空指针,使用free()释放
1.1void *malloc (int size);
说明:向系统申请长度为size的内存,返回类型是void*型,但是可以强制转换成其他类型的指针。
也就是说当你申请内存的时候,系统还不知道你用这段内存存储什么类型的数据。
1.2 free()
void free(void *firstByte):该函数的意义是将之前分配给malloc的内存还给程序或者操作系统。释放内存
1.3注意事项
1.申请了内存之后必须检查是否分配成功
2.当不需要使用时,记得释放,释放之后记得把指向该内存的指针只想NULL,免得不小心使用
3.这两个函数必须配对,如果申请后不释放就是内存泄露,如果无故释放那就是这块内存什么也没做
4.虽然maloc函数类型是void*,任何类型的指针都可以转换成void*,但是最好还是在前面加上强制类型转换,因为这样可以躲过编译器的检查。
1.4 malloc()到底是从哪里得到了内存空间?
答案是从堆里面,也就是说函数返回的指针是指向堆里面的一块内存,操作系统里面有一个记录空闲内存的的链表,当操作系统收到内存请求之后,就会遍历该链表,然后找到第一个内存比所申请的内存要大的堆节点,然后将堆节点删除,并将该内存分配给程序
二.new 运算符
2.1 c++中,用new和delete来动态创建和释放对象或者数组
用new动态创建对象时,只需指定其数据类型,而不必为该对象命名,new表达式返回对象的地址,可通过指针访问此对象
例如:int *pi=new int; 在堆中创建了一个整形对象,并返回该对象的地址给pi
2.2 动态创建对象的初始化
动态创建的对象可以用初始化变量的方式初始化
int *pi=new int(10); 初始化为10
string *ps=new string(10,‘9‘); 初始化为10个9
如果不提供显示初始化,那么用默认构造函数初始化,而内置类型的对象就不初始化
int *pi=new int(); 初始化为零
int *pi=new int; 没有初始化
string *ps=new string();初始化为空字符串(因为存在默认构造函数)
2.3删除动态创建的对象
delete 表达式释放指针指向的地址空间
delete pi; 释放单个对象
delete []pi; 释放数组
如果指针使用的不是new申请的内存,那么使用delete是不合法的
2.4在delete之后,重设指针的值
delete p; 之后,p变成了不确定的指针,在很多机器上,尽管p值没有明确定义,但仍然存放了他之前所指对象的地址,但是p所指向的内存已经被释放了,所以p不再有效,此时该指针变成了悬垂指针(悬垂指针:指向曾经存放对象的地址,但是对象已经不存在了),悬垂指针往往导致程序错误,而且很难检测出来,一旦删除了指针所指的对象,立刻将指针置为零,这样就非常清楚地指明指针不再指向任何对象了(int *p=0;).
2.5区分零值指针和NULL指针?
零值指针,是值为零的指针,可以是任何一种指针的类型,可以是通用变体类型 void*也可以是 char*,int *等等(int *pi=0;)
空指针,其实空指针只是一种编程概念,是人为地认为指针不提供任何地址讯息(c++中空指针指向了0地址)
2.6new分配失败时,返回的是什么?
1993年之前,c++内存分配失败后返回0,但是现在要求抛出operator new抛出 std::bad_alloc异常,但是很多c++程序是在编译器开始支持新规范写的,c++标准委员会不想放弃那些已有的遵循返回0规范的代码,所以她们提供了另外形式的operator new以及operator new[]以继续提供返回0功能,这些形式被称为无抛出,他们没用过throw,而是在使用new的入口点采用了nothrow对象
三.malloc和new的区别
(1)new返回指定类型的指针,并且可以自动计算所需要的大小
但是malloc必须有我们来计算字节数,并且返回的是void*指针,必须通过强制转换成我们需要的类型的指针
(2)new分配的对象可以通过默认构造函数或初始化的方法来进行对象的初始化
malloc只管内存分配,并不能对内存进行初始化,所以得到的值是随机的
(3)new/delete是c++运算符
malloc/free是c++/c语言的标准库函数
(4)对于非内部数据而言,光用malloc/free无法满足动态对象的要求,因为很多对象创建时自动执行构造函数,对象在消亡之前要自动执行析构函数,但是malloc/free是库函数,不是运算符,不在编译器控制权限之内,所以不能把构造函数和析构函数的任务强加给malloc/free;
但是new是可以完成动态内存分配和初始化的运算符,delete是完成清理和释放内存的运算符,不是库函数
注意:不要企图用malloc/free来完成动态对象的内存管理,应用new/delete;但是对于内部数据类型对象是没有构造函数,析构函数的,所以malloc/free和new/delete是没有区别的。
四.既然new/delete功能这么强大,为什么不把malloc/free代替了?
因为c++程序经常要调用c函数,但是c程序只能用malloc/free来管理动态内存。
五.为什么new/delete和malloc/free必须配对使用?
因为用free释放new创建的对象,对象就会不能执行析构函数而出错,用delete删除malloc申请的动态内存,结果也会导致程序出错,并且程序的可读性很差,所以必须使用new/delete,malloc/free配对使用
标签:
原文地址:http://www.cnblogs.com/jijiji/p/4852692.html