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

三、重学C++—C语言内存管理

上一章节:

二、重学C++—C语言核心-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/146191640?spm=1001.2014.3001.5502

本章节代码:

cPart2 · CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppstudy/tree/master/cPart2

cMemory.c

一、引言

在 C 语言的编程世界里,内存管理是基石般的存在。想象一下,内存就如同一个巨大的仓库,程序中的各种数据都存放在这个仓库的不同区域。合理地管理内存,就像是巧妙地安排仓库中的货物摆放,能让程序高效、稳定地运行。接下来,我们就深入探究 C 语言中内存的分区和管理。

二、内存分区

C 语言程序运行时,内存主要分为 栈区、堆区、全局区(静态区)、常量区和代码区。
  • 栈区(Stack):这就像一个自动整理的书架,函数调用时,局部变量、参数等会像书一样依次被放到书架上(入栈);函数执行完,这些书又会按照相反的顺序被拿走(出栈),操作系统会自动管理这个书架,速度非常快;
  • 堆区(Heap):类似于一个自由市场,程序员可以根据需要在这里租摊位(申请内存),用完后再把摊位还回去(释放内存)。但这个市场比较自由,管理起来需要程序员自己多操心。
  • 全局区(静态区,Global/Static):可以看作是一个公共仓库,全局变量和静态变量都存放在这里。这个仓库又分为两个区域,一个放已经初始化的货物(已初始化全局区),另一个放还没准备好的货物(未初始化全局区,BSS)。
  • 常量区(Constant):如同一个保险箱,里面存放着常量字符串等不可修改的数据。一旦数据放进去,就不能再改变,保证了数据的安全性。
  • 代码区(Code):相当于程序的剧本存放着程序的二进制代码,也就是编译后的机器指令。这个剧本是只读的,防止在演出过程中被意外修改。

三、可执行文件的内存划分

Text段,Date段,Bss段

四、堆与栈的区别

1、申请方式

  • 栈:栈内存由操作系统自动分配和释放。当函数被调用时,操作系统会自动为函数的局部变量和参数分配栈空间;函数返回时,这些空间会自动释放。
  • 堆:堆内存需要程序员手动申请和释放。使用malloccallocrealloc等函数来申请堆内存,使用free函数来释放, C++里面是用new / delete,申请释放

2、申请响应效率对比

  • 栈:栈的申请和释放速度非常快,因为操作系统只需要移动栈指针就可以完成操作,就像在书架上快速地拿放书一样。
  • 堆:堆的申请和释放相对较慢,因为需要操作系统进行复杂的内存管理操作,比如寻找合适的空闲内存块等,就像在自由市场中找合适的摊位一样。

3、存储效率对比

  • 栈:栈内存的存储效率高,因为数据的访问是连续的,符合计算机的缓存机制,能提高数据的读取速度。
  • 堆:堆内存的存储效率相对较低,因为频繁的申请和释放会导致内存碎片化,使得内存空间不能被充分利用。

4、异常情况列举,以及如何避免

  • 栈溢出:当栈空间被耗尽时,就会发生栈溢出错误。常见原因是递归调用过深或者局部变量占用空间过大。避免方法是控制递归深度,合理使用局部变量。
  • 内存泄漏:在堆内存管理中,如果忘记释放已经申请的内存,就会造成内存泄漏。避免方法是在使用完堆内存后,及时调用free函数释放。
实例代码:
#include <stdio.h>
#include <stdlib.h>

// 全局变量,存放在全局区
int global_var = 10;

// 未初始化的全局变量,存放在BSS区
int global_var_uninit;

// 静态变量,存放在全局区
static int static_var = 20;

// 未初始化的静态变量,存放在BSS区
static int static_var_uninit;

void func() {
    // 局部变量,存放在栈区
    int local_var = 30;
    printf("局部变量: %d\n", local_var);
}

int main() {
    // 局部变量,存放在栈区
    int local_var = 40;

    // 动态分配的内存,存放在堆区
    int *heap_var = (int *)malloc(sizeof(int));
    if (heap_var != NULL) {
        *heap_var = 50;
    }

    // 常量字符串,存放在常量区
    const char *const_str = "Hello, World!";

    printf("全局变量: %d\n", global_var);
    printf("未初始化的全局变量: %d\n", global_var_uninit);
    printf("静态变量: %d\n", static_var);
    printf("未初始化的静态变量: %d\n", static_var_uninit);
    printf("局部变量: %d\n", local_var);
    if (heap_var != NULL) {
        printf("堆区动态分配变量: %d\n", *heap_var);
        // 释放堆区内存,避免内存泄漏
        free(heap_var);
    }
    printf("常量字符串: %s\n", const_str);

    // 调用函数,观察栈区局部变量
    func();

    return 0;
}

运行结果:

下一章节:

四、重学C++—CPP基础-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/146298585

相关文章:

  • PyTorch 面试题及参考答案(精选100道)
  • 圆弧插补相关算法汇总(C++和ST源代码)
  • Spring6: 1概述
  • 拆解美团2024年报,业务协同、生态共赢、科技创新
  • POP点、LT、DX、YD
  • 20250322 c++gesp三级编程题答案
  • Linux shell脚本2-test条件测试语句:文件类型、字符串是否相等、数字大小比较、多重条件判断,测试语句验证
  • Kafka消息序列化深度革命:构建高性能、高安全的自定义编码体系
  • 从扩展黎曼泽塔函数构造物质和时空的结构-7
  • 详解c语言键盘输入联系小程序
  • 解密模型上下文协议(MCP):下一代AI交互框架
  • 使用密码连接Redis服务的两种方式
  • Linux的Autojump库的安装和使用
  • pyecharts在jupyter notebook中不能够渲染图表问题。
  • el-table表格toggleRowSelection方法选中无效
  • 23种设计模式-单例(Singleton)设计模式
  • 文件的分片上传vs流失上传
  • 【2025】基于node.js的中医药科普平台的设计与实现(源码、万字文档、图文修改、调试答疑)
  • 解决Enable-WindowsOptionalFeature : 功能名称 Microsoft-Hyper-V 未知。
  • Linux驱动开发进阶(二) - sysfs文件系统
  • 全球最大汽车板供应商宝钢股份:汽车工业加速转型中材料商如何共舞?
  • 解放日报:服务国家战略,加快建成科技创新高地
  • “面具女孩”多次恐吓电梯内两幼童,当事女孩及家长道歉后获谅解
  • 看见“看得见的手”,看见住房与土地——读《央地之间》
  • 俄罗斯延长非法滞留外国人限期离境时间至9月
  • 老凤祥一季度净利减少两成,去年珠宝首饰营收下滑19%