C&C++ 内存管理 #9
JAX1024Dev
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
#前言
640K ought to be enough for every body. -- Bill Gates
一、内存分配方式
根据分配内存的方法,C++有 3 种经典管理内存的方法:
1.1 自动存储
在函数内部定义的常规变量使用自动存储,这些变量被称为 automatic variable。
生存周期:它们所属的函数被调用时自动产生,在该函数结束时消亡。
存储位置:通常存储在栈中。
实际上,其生存周期为整个函数运行期间是片面的。更确切的说法是,自动变量是一个局部变量,其作用域为包含它的代码块。函数是我们最常见的代码块。当执行代码块时,自动变量依次进栈,而在离开代码块时,按相反顺序释放这些变量。
默认情况下,函数参数也是自动变量之一。
1.2 静态存储
静态存储是整个程序执行期间都存在的存储方式。内存在程序编译时分配好。静态变量的数目在程序运行的期间都是不变的,没有特别的装置(如栈)来管理它们。
所有变量静态持续变量的初始化特征:如果没有显示地初始化它们,编译器将它们所有位设为0。默认情况,静态数组和结构每个元素都是0。这被称为零初始化 zero-initialized
生存周期:这块内存在程序的整个运行期间都存在。
C++ 中为静态存储持续性变量提供了 3 种链接性:
1.2.1 静态变量初始化
初始化时机:前两种被称为静态初始化,意味着在编译器处理文件时就初始化变量。动态初始化意味着将在编译后初始化。
初始化顺序:
1.2.2 外部链接性
链接性为外部的变量通常称为外部变量,它们的存储持续性为静态。也被称为全局变量。
规则:
为此,C++ 提供了两种变量声明:定义声明和引用声明。前者给变量分配存储空间,后者不分配。
引用声明使用关键字
extern且&不进行初始化。二者缺一不可。1.2.3 内部链接性
静态外部变量。将 static 限定符用于作用域为整个文件的变量时,该变量的链接性为内部的。链接性为内部的变量只能在其所属的文件中使用。
以上示例并不违反单定义原则,静态变量将隐藏常规外部变量。
1.2.4 无链接性
将 static 限定符用于在代码块中定义的局部变量。这将导致该局部变量的存储持续性为静态的,这意味着它在包含它的代码块不处于活跃状态时仍然存在。因此,在两次函数调用之间,静态局部变量的值将保持不变。
关于初始化,如果初始了静态局部变量,则程序只在启动时进行一次初始化,以后再调用函数时,将不会像自动变量那样再此被初始化。
1.3 动态存储
程序在运行的时候用 malloc 或 new 申请任意多少的内存,程序猿自己负责在何时用 free 或 delete 释放内存。动态内存的生存期由我们自己决定,使用非常灵活,但问题最多。
存储位置:堆
1.3.1 有了 malloc/free 为什么还要 new/delete?
本质区别:malloc/free 是标准库函数,new/delete 是 C++ 运算符。
对于非内部数据类型的对象而言,只用 malloc/free 是无法满足动态对象的要求。对象在创建时需要执行构造函数,在消亡之前需要执行析构函数。由于 malloc/free 是库函数而不是运算符,不在编译器的控制权限之内就,不能够把执行构造函数和析构函数的任务强加于 malloc/free。
为什么不把 malloc/free 淘汰出局呢?C 语言只能用 malloc/free,而 C++ 经常调用 C 程序,如果用 free 释放 new 创建的动态对象,会导致出错。
二、常见的内存错误及其对策
内存错误与三类指针
参考文献
Beta Was this translation helpful? Give feedback.
All reactions