上一章节:
二、重学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、calloc、realloc等函数来申请堆内存,使用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
