C++基础知识(四)--C++内存管理--函数的调用机制及返回值--作用域与标识符的可见性--标识符的生命期
一、C++内存管理
1.操作系统为一个C++程序的运行所分配的内存分为5个区
- 堆:堆是操做系统的术语,是操作系统所维护的一块特殊内存,用于程序的动态内存分配。c语言使用malloc从堆上分配内存,使用free释放已经分配的内存。
- 栈:主要用来存放局部变量,在函数执行时,函数内部局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放,栈内存分配运算内置于处理器的指令中,效率很高,但分配的内存容量有限。
- 自由存储区(一个抽象概念):自由存储区时C++基于new操作符的一个抽象概念,凡是通过new操作符申请的内存即为自由存储区。
- 全局/静态存储区:存放全局数据和静态数据。这块内存时在程序编译的时候就分配好的在程序整个运行期间都存在。全局变量与静态变量
- 常量存储区:一块比较特殊的存储区,里边存储的是常量(const),不允许修改
2.自由存储区与堆的区别?自由存储区与堆是两块不同的存储区域吗?他们有可能相同吗?
- malloc在堆上分配内存块,使用free释放内存块,new申请的内存块在自由存储区,使用delete释放
- 堆是C语言和操作系统的术语。堆是操作系统所维护的一块特殊内存,他提供了动态内存分配的功能,当程序调用malloc()时就会从堆中分配内存,稍后调用free()释放内存。而自由存储区是C++中通过new,delete动态分配和释放对象的抽象概念,通过new()申请的内存区域成为自由存储区。基本上所有的C++编译器默认使用堆来实现自由存储。即缺省的全局运算符new,delete也会按照malloc,free的方式来实现。这时由new运算符分配的对象,说他在堆上也对在自由存储区也对。但程序员也可以通过重载运算符,改用其他内存来实现自由存储区,这时自由存储区就有别于堆了。
-
堆是操作系统所维护的一块特殊内存区域,自由存储区是C++通过new,delete动态分配和释放对象的抽象概念,两者不等价。
3.堆与栈的区别
详见https://www.cnblogs.com/southcyy/p/10167005.html
c语言内存分区的博客文章
4.new与malloc区别
详见后续博客单独写
二、C++函数调用机制与函数返回值
1. 函数的调用过程
- 建立栈空间;
- 保护现场:主调函数运行状态与返回地址入栈
- 为被调函数中的局部变量分配内存空间,完成参数传递
- 执行被调函数函数体
- 释放被调函数中局部变量占用的栈空间
- 恢复现场:取主调函数的运行状态与返回地址,释放栈空间
- 继续主调函数后续语句
2.函数的返回值
return语句:返回值是如何回到调用处的
在函数返回时,系统会在内存中建立一个临时变量,函数返回时将函数值保存在该临时变量中,然后由主调函数中包含调用的表达式语句从该临时变量中取得值,表达式语句执行后该临时变量撤销。
三、作用域与标识符的可见性
1.作用域:指标识符能够被使用的范围。只有在作用域内标识符才可以被访问。
- 局部作用域
- 块域:大括号括起来的程序段。对于块中嵌套其他块的情况,如果嵌套块中有同名局部变量服从局部优先原则,即在内层块中屏蔽外层块中的同名变量。即内层块中局部变量的作用域为内层块,外层块中局部变量的作用域为外层出去包含同名变量的内存块部分。如果块内定义的局部变量与全局变量同名,块内仍然局部变量优先,但在块内可以通过域运算符::访问同名的全局变量
- 函数声明域:函数声明不是定义函数,在做函数声明时,其中的形参作用域只在声明中,即作用域结束于右括号。正是由于形参不能被程序的其他地方引用,所以只要声明形参的个数与类型即可,形参名可省略。
- 文件域:文件域即全局域。定义在所有函数之外的标识符作用域为从定义处到整个源文件结束。。如果某个文件中说明了作用域为文件域的标识符,该文件又被另一个文件包含,则该标识符的作用域延伸到新的文件中。
- 类的作用域与命名空间作用域:详见域运算符::
四、标识符的生命期
1.静态生命期
2.局部生命期
3.动态生命期