当前位置: 首页 > news >正文

014存储期(时间)

一、基本概念

        C语言中,变量都是有一定的生存周期的,所谓生存周期指的是从分配到释放的时间间隔。为变量分配内存相当于变量的诞生,释放其内存相当于变量的死亡。从诞生到死亡就是一个变量的生命周期。

根据定义方式的不同,变量的生命周期有三种形式:

1. 自动存储期 --- 函数死,变量就死

2. 静态存储期 --- 程序死,变量才死(普通函数死它不会死(除了main函数))

3. 自定义存储期 --- 程序员让它死,它才死(或者程序死了,它才死) ---- 君要臣死,臣不得不死

不同存储区段对应不同存储期

解析:

自动存储期(栈区): 主要矛盾,注意内存分配不要过大

自定义存储期(堆区): 主要矛盾,申请的内存资源,需要及时释放,否则会造成内存泄漏

静态存储期(数据段): 主要矛盾,数据段的数据(比如全局变量)尽量不要太多

二、自动存储期

在栈内存中分配的变量,通通拥有自动存储期,因此也都被称为自动变量。这里自动的含义,指的是这些变量的内存管理不需要开发者操心,都是全自动的:在变量定义处自动分配,出了变量的作用域后自动释放。

  • 以下三个概念是等价的:
    • 自动变量:从存储期的角度,描述变量的时间特性。
    • 临时变量:同上。
    • 局部变量:从作用域的角度,描述变量的空间特性。

可以统一把它们称为栈变量,下面是示例代码:

  • 示例代码:
#include <stdio.h>
// 普通函数(栈内存不能超过1MB, 所以建议使用堆空间)
int func(int a, int b)      
{
    char buf[1024*1005] = {0};   
    return a+b;
}

// 主函数
int main(int argc, char const *argv[])   // 主函数的栈内存不要超过8MB否则会爆内存
{
    // (1)、自动存储期  --- 出了花括号{}限定的范围,就死
    int num1 = 100;         // main函数死了,就死
    int num2 = 200;         // main函数死了,就死


    // 1、在变量定义处自动分配,出了变量的作用域后自动释放
    if (num1<200)
    {
        char buf1[1024*1024*7] = {0};   // 只要出了外面的花括号{},就死(内存被系统释放了)
    }
    
    {
        char buf1[1024*1024*7] = {0};   // 只要出了外面的花括号{},就死(内存被系统释放了)
    }
    
    // 2、调用函数
    int ret = func(100, 200);           // 普通函数的栈内存,最好不要超过1MB否则会爆内存
    printf("ret == %d\n", ret);
    
     return 0;
}

三、静态存储期

在数据段中分配的变量,通通拥有静态存储期,因此也都被称为静态变量。这里静态的含义,指的是这些变量的不会因为程序的运行而发生临时性的分配和释放,它们的生命周期是恒定的,跟整个程序一致。

  • 静态变量包含:
    • 全局变量:不管加不加 static,任何全局变量都是静态变量。
    • static 型局部变量。
  • 注意1:
    • 若定义时未初始化,则系统会将所有的静态数据自动初始化为0
    • 静态数据初始化语句,只会执行一遍。
    • 静态数据从程序开始运行时便已存在,直到程序退出时才释放。
  • 注意2:
    • static修饰局部变量:使之由栈内存临时数据,变成了静态数据。
    • static修饰全局变量:使之由各文件可见的静态数据,变成了本文件可见的静态数据。
  • 示例代码:
#include <stdio.h>

// 2、普通全局变量、静态全局变量
int num5;               // 数据段中的bss区域, 全局变量,整个工程的文件都可以访问它
int num6 = 600;         // 数据段中的data区域, 全局变量,整个工程的文件都可以访问它
static int num7;        // 数据段中的bss区域, 静态全局变量,本文件可见,工程里面的其它文件不可见
static int num8 = 800;  // 数据段中的data区域, 静态全局变量,本文件可见,工程里面的其它文件不可见

// 主函数
int main(int argc, char const *argv[])   
{ 
    // 1、静态局部变量
    static int num3;                    // 数据段中的bss区域, static局部变量,本函数可见
    static int num4 = 400;              // 数据段中的data区域, static局部变量,本函数可见
}

四、自定义存储期

在堆中分配的变量,统统拥有自定义存储期,也就是说这些变量的分配和释放,都是由开发者自己决定的。由于堆内存拥有高度自治权,因此堆是程序开发中用得最多的一片区域。

自由的堆内存

  • 相关API:
    • 申请堆内存:malloc() / calloc()
    • 清零堆内存:bzero()
    • 释放堆内存:free()

  • 注意:
    • malloc()申请的堆内存,默认情况下是随机值,一般需要用 bzero() 来清零。
    • calloc()申请的堆内存,默认情况下是已经清零了的,不需要再清零。
    • free()只能释放堆内存,不能释放别的区段的内存。
  • 释放内存的含义:
    • 释放内存意味着将内存的使用权归还给系统。
    • 释放内存并不会改变指针的指向。
    • 释放内存并不会对内存做任何修改,更不会将内存清零。(看情况)
  • 示例代码:
#include <stdio.h>
int main(int argc, char const *argv[])  
{
    char *p = malloc(100);              // 程序员需要使用free函数去杀了它(释放它),否则其内存会一直存在(也就是会造成内存泄漏),直到程序结束为止
    bzero(p, 100);
    free(p);

    return 0;
}

至此,希望看完这篇文章的你有所收获,我是Bardb,译音八分贝,道友,下期见!

相关文章:

  • Qt之QStateMachine等待
  • C++20 Lambda表达式新特性:包扩展与初始化捕获的强强联合
  • Is Noise Conditioning Necessary for Denoising Generative Models?论文阅读笔记
  • 开源向量数据库Milvus简介
  • RNN实现精神分裂症患者诊断(pytorch)
  • 在日常工作中,有一块新磁盘,如何扩容到vm中,具体命令是什么?
  • XSL 语言:XML 样式表的语言基础与应用
  • 初识uniApp
  • 【Java项目】基于SpringBoot的Java学习平台
  • 在Ubuntu中,某个文件的右下角有一把锁的标志是什么意思?
  • 在什么情况下需要使用光谱相机呢?
  • 《Neurocomputing》投稿历程
  • 从UNIX到Linux:操作系统进化史与开源革命
  • 模拟器DTXMania的DTX文件格式规范
  • 挺逼真:AI绘画+AI扩图,已解锁,无限次生成~~~
  • 「Selenium+Python自动化从0到1②|2025浏览器操控7大核心API实战(附高效避坑模板))」
  • 基于trl复现DeepSeek-R1的GRPO训练过程
  • python之线程池ThreadPoolExecutor笔记
  • 单片机栈和堆、FALSH、区别
  • OpenEuler学习笔记(三十五):搭建代码托管服务器
  • 重庆网站建设公司价格/短视频询盘获客系统
  • 诸城做网站/百度小说搜索风云榜排名
  • 长春建站公众号/网络营销的有哪些特点
  • 免费做暧暧网站/上海关键词排名软件
  • 冠县哪里有做网站的/优化推广网站怎么做
  • 企业网站404页面设计/aso优化什么意思是