内存学习(一)内存四区分配

一、C语言程序的内存组成

对于C语言程序来说,所占用的内存主要有以下几个部分:代码区(所写的C语言的代码以及数据)、静态常量(字符常量)区(定义的字符串常量)、已初始化全局数据区(全局变量被初始化)、未初始化全局数据区、堆区、栈区
栈区往地址减小方向增长,堆区往地址增大方向增长
main函数以及自己定义的函数具有临时性,因此在栈上开辟空间,开辟的空间大小由变量的类型所决定。开辟的空间为栈帧
假设地址总线是32位,那可寻址的范围是4G,内存地址即0 - 0xffffffff
在这里插入图片描述

二、内存四区划分

内存划分为4个区域:

  1. 代码区:存放函数体的二进制代码,由操作系统进行管理的
  2. 全局区:存放全局变量和静态变量以及常量
  3. 栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
  4. 堆区:由程序员分配和释放,若程序员不释放,程序结束后由操作系统回收
内存分区名称 内容 权限
栈区 函数中的普通变量 可读可写
堆区 动态申请的内存 可读可写
静态变量区 static修饰的变量 可读可写
数据区 用于初始化变量的常量 只读
代码区 代码指令 只读

2.1 代码区

  1. 代码区存放CPU执行的机器指令既程序汇编而成的二进制代码
  2. 代码区是共享的,对于频繁执行的程序,内存中只需要保存一份即可
  3. 代码区是只读的,只读的原因是防止程序意外修改了指令

2.2 全局区

在这里插入图片描述

2.3 栈区

由编译器自动分配释放,存放函数的参数值,局部变量等。
注意:不要返回局部变量的地址,栈区开辟的地址由编译器自动释放

2.4 堆区

由程序员分配释放,若程序员不释放,则程序结束时由操作系统回收,主要利用 malloc 关键字开辟堆区

三、 堆和栈的区别

3.1 申请方式

栈区 stack:由系统自动分配,在运行时赋值,只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出
例如,在函数中声明一个局部变量 int a; 系统自动在栈中为 a 开辟空间

堆区 heap: 需要程序员自己申请,并指明大小,在编译时确定,在 C语言 中使用malloc函数,必须 free 语句才能正确的释放该内存空间
例如:char * p1; p1 = (char *)malloc(10);

3.2 申请的地址大小

:栈是向低地址扩展的数据结构,是一块连续的内存的区域,由系统自动分配,速度较快,但程序员是无法控制

:堆是向高地址扩展的数据结构,是不连续的内存区域,速度比较慢,易产生内存碎片

3.3 堆和栈中的存储内容

: 在函数调用时,第一个进栈的是主函数中后的下一条指令的地址,然后是函数的各个参数,参数是由右往左入栈的,然后是函数中的局部变量。静态变量不入栈。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,程序由该点继续运行

:一般是在堆的头部用一个字节存放堆的大小,具体内容由程序员安排

猜你喜欢

转载自blog.csdn.net/future_sky_word/article/details/125704903