问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C/C++内存四区详解:栈区、堆区、静态区和代码区

创作时间:
作者:
@小白创作中心

C/C++内存四区详解:栈区、堆区、静态区和代码区

引用
CSDN
1.
https://blog.csdn.net/m0_57333603/article/details/138154043

在C/C++编程中,内存管理是一个核心概念。程序运行时,内存被划分为四个主要区域:栈区、堆区、静态区(全局区)和代码区。每个区域都有其特定的功能和使用场景。本文将详细介绍这四个内存区域的特点及其相互之间的区别。

代码区

代码区是一个只读区域,在程序运行过程中不能被修改。它主要存放程序编译后生成的可执行程序(二进制代码),以及一些只读常量,如常量字符串。这些常量字符串通常存放在rodata段

静态区(全局区)

静态区也被称为全局区或数据区,主要用于存放全局变量、全局常量和静态变量。这一部分可以进一步细分为bss段和data段:

  • bss段:主要存放未初始化的全局变量和静态变量,或者是初始化为0的全局变量和静态变量。
  • data段:主要存放初始化非零的全局变量和静态变量。

堆区

堆区的内存需要由程序员自己进行开辟和释放。在C语言中,可以使用malloccallocrealloc等函数来开辟内存,使用free函数释放内存;在C++中,则使用new来开辟内存,使用delete释放内存。堆区的空间相对较大,用于动态分配内存。需要注意的是,堆区开辟的内存不会在函数结束时自动释放,而是需要程序员手动释放。堆区的地址分配是从低地址向高地址扩展,且空间分配是不连续的,类似于链表的形式,因此容易产生内存碎片

栈区

栈区的内存由编译器自动管理,无需程序员干预。它主要用于存放局部变量、局部常量、函数的参数和返回值。栈区的容量相对较小,但地址是连续分配的。栈空间的分配是从高地址向低地址扩展,并遵循先进后出(LIFO)的原则。

以函数调用为例:当func调用func1时,func中的局部变量先入栈;接着执行func1时,func1中的局部变量入栈;如果func1中又调用func2,那么func2中的局部变量也会入栈。当函数执行完毕后,局部变量会被销毁并出栈,整个过程遵循先进后出的原则。

堆区和栈区的区别

  1. 管理方式:栈区通常由编译器自动管理,无需程序员干预;堆区则由程序员通过动态内存分配函数(如mallocnew)自行分配和释放。
  2. 空间大小:栈区的容量相对较小,通常在几百KB到几MB之间,主要用于存储局部变量和函数调用的临时数据;堆区的空间较大,用于动态分配和管理的数据结构,如动态数组、字符串、对象等。
  3. 碎片问题:栈区因为采用后进先出(LIFO)的管理方式,通常不会产生内存碎片;堆区由于频繁的动态分配和释放,容易导致内存碎片,影响效率。
  4. 生长方式:栈区向低地址扩展,空间连续;堆区向高地址扩展,空间不连续,类似于链表结构。
  5. 访问速度:栈区的访问速度通常比堆区快,因为栈区的数据直接存放在系统内存中,而访问堆区数据需要通过指针进行间接访问。

示例

在内存布局中,内核空间是操作系统专用的,用户程序无法访问。内存四区按照地址从高到低的顺序排列为:栈区、堆区、全局区和代码区。如下图所示:

  • 红色部分:全局变量、静态全局变量和静态局部变量都存放在全局区。
  • 蓝色部分:局部变量的变量名以及函数返回值存放在栈区。
  • 黄色部分:动态开辟的内存存放在堆区。
  • 绿色部分:常量字符串存放在代码区。

可以看出,局部变量的指针可能指向栈区、堆区或代码区。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号