1、
2、明确
对于非内部数据类型的对象而言,光用
内存分配方式
简介
在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算
内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
堆:就是那些由 new
分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new
就要对应一个 delete
。如果
程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
自由存储区:就是那些由malloc
等分配的内存块,他和堆是十分相似的,不过它是用free
来结束自己的生命的。
全局/静态存储区:全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在
C++里面没有这个区分了,他们共同占用同一块内存区。
常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。
2、明确
- 内存分配虽然成功,但是尚未初始化就引用它
区分堆与栈
void f(){
int *p=new int[10];
}
这条短短的一句话就包含了堆与栈,看到
new
,我们首先就应该想到,我们分配了一块堆内存,那么指针
p
呢?他分配的是一块
栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针
p
3、堆和栈究竟有什么区别
(1). 管理方式不同
对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生
(2). 空间大小不同
memory leak
。
一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有
一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M(好像是,记不清楚了)。当然,我们可以修改:
4、控制C++的内存分配
常见的内存错误及其对策
- 内存分配未成功,却使用了它;
- 内存分配虽然成功,但是尚未初始化就引用它
- 内存分配成功并且已经初始化,但操作越过了内存的边界
- 忘记了释放内存,造成内存泄露
- 释放了内存却继续使用它:使用
free
或delete
释放了内存后,没有将指针设置为NULL
。导致产生“野指针”。
5、有了malloc/free为什么还要new/delete
malloc
与free
是C++/C语言的标准库函数,new/delete
是C++的运算符。它们都可用于申请动态内存和释放内存。
对于非内部数据类型的对象而言,光用
maloc/free
无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消
亡之前要自动执行析构函数。由于
malloc/free
是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数
的任务强加于
malloc/free
。
因此C++语言需要一个能完成动态内存分配和初始化工作的运算符
new
,以及一个能完成清理与释放内存工作的运算符delet
e。
注意
new/delete
不是库函数。我们先看一看malloc/free
和new/delete
如何实现对象的动态内存管理