08 – 数据结构基础知识补充

内存分类

一、静态 / 全局内存(程序运行期间一直存在)

特点:全局变量和静态变量(用static声明)的内存,在程序启动时分配,程序结束才释放。
通俗理解:像「公共仓库」,一旦创建就一直存在,所有需要的地方都能访问(全局变量),或在特定范围内持续保留(静态变量)。

#include <stdio.h>

// 全局变量(属于静态/全局内存)
int global_var = 10;  

void show_static() {
    // 静态变量(属于静态/全局内存)
    static int static_var = 20;  
    static_var++;  // 每次调用都会保留上一次的值
    printf("静态变量: %d\n", static_var);
}

int main() {
    printf("全局变量初始值: %d\n", global_var);  // 输出10
    global_var = 100;  // 修改全局变量
    printf("修改后全局变量: %d\n", global_var);  // 输出100

    show_static();  // 第一次调用:静态变量=21
    show_static();  // 第二次调用:静态变量=22(值被保留)
    return 0;
}

解释

  • global_var是全局变量,整个程序都能访问,修改后值会一直保留。
  • static_var是函数内的静态变量,虽然在函数里声明,但不会因函数结束而消失,下次调用函数时会继续使用上次的值。

二、自动内存(栈内存,函数调用时临时创建)

特点:函数内的普通局部变量(不用static声明),内存由编译器自动分配 / 释放,函数调用时创建,函数返回时销毁。
通俗理解:像「临时储物柜」,只在函数执行期间使用,函数结束后里面的东西就被清空,下次再调用函数时会重新分配新的空间。

#include <stdio.h>

void temp_var_demo() {
    int temp = 100;  // 自动内存(栈内存)
    printf("函数内temp值: %d\n", temp);  // 输出100
}  // 函数结束,temp的内存被自动释放

int main() {
    temp_var_demo();  // 调用函数,temp被创建并使用
    // 下面这行代码会报错:temp是函数内的局部变量,main函数无法访问
    // printf("函数外temp值: %d\n", temp);  
    return 0;
}

解释

  • temptemp_var_demo函数内的局部变量,只在函数执行时存在。函数结束后,temp的内存会被自动回收,其他函数(如main)无法访问它。

三、动态内存(堆内存,手动分配和释放)

特点:通过malloc/calloc等函数手动申请内存,需用free手动释放(否则会内存泄漏)。内存生命周期由代码控制,不依赖函数调用。
通俗理解:像「自己租的仓库」,需要时自己申请(malloc),不用了自己退租(free),租期完全由你决定。

#include <stdio.h>
#include <stdlib.h>  // 包含malloc和free的函数声明

// 函数返回动态分配的内存地址
int* create_dynamic_memory(int size) {
    // 申请能存size个int的内存(每个int占4字节,共4*size字节)
    int* arr = (int*)malloc(size * sizeof(int));  
    if (arr == NULL) {  // 检查是否分配成功(内存不足时可能失败)
        printf("内存分配失败!\n");
        exit(1);  // 异常退出程序
    }
    // 初始化内存(比如全部设为0)
    for (int i = 0; i < size; i++) {
        arr[i] = i;
    }
    return arr;  // 返回内存地址(函数结束但内存不会被释放)
}

int main() {
    int* my_arr = create_dynamic_memory(5);  // 调用函数,获得动态内存

    // 使用内存(输出:0 1 2 3 4)
    for (int i = 0; i < 5; i++) {
        printf("%d ", my_arr[i]);
    }

    free(my_arr);  // 手动释放内存(必须!否则内存泄漏)
    my_arr = NULL;  // 避免“野指针”(指向已释放内存的指针)
    return 0;
}

解释

  • malloc申请的内存不会因函数(如create_dynamic_memory)结束而自动释放,必须用free手动释放。
  • 如果忘记free,这部分内存会一直被占用(内存泄漏),直到程序结束。

总结对比

内存类型分配方式释放方式生命周期典型用途
静态 / 全局内存程序启动时自动分配程序结束时自动释放程序运行全程全局状态、需要跨函数保留的值
自动内存(栈)函数调用时自动分配函数返回时自动释放函数执行期间临时计算的局部变量
动态内存(堆)手动调用malloc手动调用free释放手动控制(直到free需要灵活控制大小或跨函数使用的内存

四、知识点补充

本网站原创文章版权归何大锤的狂飙日记所有。发布者:何大锤,转转请注明出处:何大锤的博客

(0)
何大锤的头像何大锤管理团队

相关推荐

  • 第二章数据结构线性表 – 单链表动画演示

    一、带头结点单链表 1、头插法创建-动画演示 2、尾插法创建-动画演示 3、插入操作 插入表头 插入中间 插入表尾

    2025年6月16日
    800
  • 第二章数据结构线性表 – 单链表的插入和删除操作

    一、知识要点 1.1 按位序插入 – 带头结点 1.2 按位序插入 – 不带头结点 1.3 指定结点的后插操作 1.4 指定结点的前插操作 1.5 按位序删除(带头结点) 1.6 指定结点删除 1.7 封装的好处 二、单链表 – 插入操作 3.1 按位序插入(带头结点) – ListInsert(&L,…

    2025年6月16日
    300
  • 第二章数据结构线性表 – 单链表的定义与初始化

    一、单链表的定义和表示 – 知识要点 1.1 定义单链表 1.2 带头结点单链表的初始化 二、单链表 – 定义与初始化 1.1 带头结点代码实现 1.1.1 C语言实现 实现算法实现 测试主函数 运行结果 运行过程 带头结点单链表的初始化的注意点 1.1.2 C++单链表定义及初始化 运行结果 1.2 不带头结点代码实现 1.2.1 …

    2025年6月14日
    700
  • 第二章数据结构线性表 – 单链表概念

    一、引言 1.1 知识框架 1.2 有了数组为什么还要链表? 在前面我们介绍过数组,数组中元素是存储在连续的内存位置在声明数组时,我们可以指定数组的大小,但这将限制数组可以存储的元素数量 例如我们声明的是 int arr[10],那么arr数组最多可以存储10个数据元素 但是我们事先不知道元素的大小呢? 我们该如何去做? 当然首先想到的是申请一个足够大的数组…

    2025年6月14日
    300
  • 07 – 第二章数据结构线性表 – 顺序表总结

    顺序表代码实现 一、动态分配方式实现的所有功能 dynamic_list.c dynamic_list.h relloc函数 realloc 是 C 语言标准库中用于重新调整已分配内存块大小的函数,主要用于动态内存管理(头文件 <stdlib.h>)。 ptr:指向待调整大小的原内存块的指针(若为 NULL,效果等价于 malloc…

    2025年5月29日
    700

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

2211932694

在线咨询: QQ交谈

邮件:hdcblog1999@163.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
网站建设中ing......