17-C语言中的变量生命周期——自动存储期、青苔存储期、自定义存储期
文章目录
- 17-C语言中的变量生命周期——自动存储期、青苔存储期、自定义存储期
- 一、自动存储期
- 示例
- 二、静态存储期
- 2.1 示例
- 三、自定义存储期
- 3.1 如何申请内存
- 3.2 如何释放内存
- 3.3 如何清空内存
- 3.4 示例
概念
在C语言中,每个变量都有一个生命周期,即从变量的内存申请到释放的过程。申请内存相当于变量的诞生,释放内存则相当于变量的消亡。变量的生命周期有以下三种形式:
- 自动存储期
- 静态存储期
- 自定义存储期
一、自动存储期
自动存储期的变量在栈空间中分配,内存由系统统一管理
。自动存储期的几个等价概念包括:
- 自动化变量:从存储期的角度来描述变量的存储特性
- 临时变量: 从存储期的角度来描述变量的存储特性
- 局部变量: 从作用域的角度来表述变量的空间特定
示例
int main(int argc, char const *argv[]) // argc 和 argv 属于自动存储期的局部变量
{
int a; // 自动存储期 / 局部变量
static int b; // 静态存储期的局部变量
func(a, b);
}
void func(int x, int y) // x 和 y 属于自动存储期的局部变量
{
// 函数体
}
二、静态存储期
静态存储期的变量在数据段
中分配,内存在程序运行之初就已经分配好,并且不会随着程序的运行发生申请和释放的问题。静态存储期的变量直到整个程序退出才会释放
,生命周期与进程一致。
- 全局变量,static只是影响他的作用域,并不影响他的存储期.
- static修饰的局部变量,对于局部变量而言static只是改变了变量的存储期,而没有改变他的作用域.
2.1 示例
int a = 100; // 静态存储期
static int b = 250; // 静态存储期,作用域为本文件
int main()
{
int k; // 自动存储期 / 局部变量
static int k = 450; // 静态存储期的局部变量
}
注意:
.bss
段存放未初始化
的静态变量,初始值为0
。.data
段存放已经初始化
的静态变量,初始化语句只会被执行一次
。- 静态数据从进程运行之初就已经存在,直到进程退出为止。
三、自定义存储期
自定义存储期的变量在堆内存中分配,内存的申请与释放完全由用户自己控制。
3.1 如何申请内存
malloc
:只负责申请空间,不会清空内存。calloc
:申请内存并默认清空为 0。
3.2 如何释放内存
free
:负责释放内存,但不会清空内存,也不会让指针指向空,释放后最好将指针设为NULL
。
3.3 如何清空内存
bzero
memset
注意:
malloc
只负责申请空间, 并不会清空内存,因此一般使用bzero 清空calloc
负责申请内存,并会默认清空为 0 .free
只负责释放,也不会清空 更不会让指针指向空, 因此free之后最好让指针指向NULL.
3.4 示例
#include <stdlib.h>
#include <string.h>
int main()
{
int *p = (int *)malloc(10 * sizeof(int)); // 申请内存
if (p == NULL) {
// 处理内存分配失败的情况
return -1;
}
// 清空内存
memset(p, 0, 10 * sizeof(int));
// 使用内存...
// 释放内存
free(p);
p = NULL; // 释放后将指针设为 NULL
}
总结:
- 自动存储期:变量在栈上分配,生命周期由系统管理,函数结束时自动释放。
- 静态存储期:变量在数据段中分配,生命周期与程序一致,程序结束时释放。
- 自定义存储期:变量在堆上分配,生命周期由用户管理,用户需要手动申请和释放内存。