一、内存管理
实例分析
二、堆和栈
对于栈来讲,是编译器自动管理,无需我们手动控制;对于堆来说,释放工作由程序员控制
对于栈来讲,生长方向是向下的,也就是向着内存减小的方向;对于堆来讲,它的生长方向是向上的,是向着内存地址增加的方向增长
对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题
一般来讲在32位系统下,内存可以达到4G的空间,并不会把所有空间分配给堆空间,但是对于栈来讲,一般都是有一定的空间大小的
只有栈可以静态分配,堆和栈都可以动态分配
三、malloc和new
从属性上来讲:
new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要头文件支持
从参数上来讲:
使用new操作符申请内存分配时无需指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
从返回类型来讲:
new符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void*,需要通过强制类型转换将void*指针转换成我们需要的类型。
从分配失败来讲:
new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时会返回NULL。
从自定义类型来讲:
new会调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。
malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。
特性分析
使用char*p=new char[100]申请一段内存,然后使用delete p释放,有什么问题?
会在程序编译过程中报错,new char[]过程中系统会在申请内存前开辟4个字节的空间来存储调用了多少次构造函数,并返回更新之后的地址。delete时不是利用delete [] p,会导致free时访问地址出错。
模板
1.可用来创建动态增长和减小的数据结构,但并不是使用必须使用模板的原因
2.它是类型无关的,因此具有很高的可复用性
3.它运行时检查数据类型,保证了类型安全
4.它是平台无关的,可移植性
5.编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础
模板分为函数模板和类模板
1.类模板中的成员函数全是模板函数
2.类模板与模板类所指的不是同一概念,类模板是一个模板,是类的抽象,模板类是一个类,用类模板生成的类
3.函数模板是一个蓝图,它本身并不是函数,是编译器使用方式产生特定具体类型函数的模具