三、重学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、申请方式

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

2、申请响应效率对比

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

3、存储效率对比

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

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

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

相关推荐
烂蜻蜓2 小时前
深度解读 C 语言运算符:编程运算的核心工具
java·c语言·前端
喜欢理工科3 小时前
18 C语言标准头文件
c语言·python·算法·c语言标准头文件
sakabu5 小时前
Linux安装MySQL数据库并使用C语言进行数据库开发
linux·c语言·数据库·笔记·mysql·数据库开发
Peter_Deng.6 小时前
单片机 - 位运算详解(`&`、`|`、`~`、`^`、`>>`、`<<`)
c语言·单片机·嵌入式硬件
阿巴~阿巴~7 小时前
2024年3月全国计算机等级考试真题(二级C语言)
c语言
王RuaRua8 小时前
[数据结构]1.时间复杂度和空间复杂度
c语言·数据结构·算法
wuqingshun3141599 小时前
蓝桥杯 R格式
c语言·c++·算法·职场和发展·蓝桥杯·r语言
努力努力再努力wz9 小时前
【c++入门系列】:引用以及内联函数详解
java·运维·服务器·c语言·开发语言·c++
三体世界10 小时前
C++ STL 序列式容器之(三)-- List
java·c语言·开发语言·c++·windows·list·visual studio
慕洋男孩11 小时前
LeetCode(977):有序数组的平方
c语言·leetcode