美文网首页C&CPP
C语言基础-内存布局(Memory Layout)

C语言基础-内存布局(Memory Layout)

作者: ruizuo007 | 来源:发表于2019-11-13 18:39 被阅读0次

计算机中的内存是分区来管理的,程序和程序之间的内存是独立的,不能互相访问,比如QQ和浏览器分别所占的内存区域是不能相互访问的。而每个程序的内存也是分区管理的,一个应用程序所占的内存可以分为很多个区域,我们需要了解的主要有四个区域,通常叫内存四区,如下图:

内存四区域

在C语言中,内存的主要分为下列几部分:

  1. Text/Code Segment 文本/代码区

  2. Initialized Data Segments 初始化的数据区

  3. Uninitialized Data Segments 未初始化的数据区

  4. Stack Segment 栈区

  5. Heap Segment 堆区

内存布局

Text/Code Segment 文本/代码区

这个区主要用来保存机器代码,一个可执行对象文件的文本区通常是只读区,可以防止程序被意外修改。文本/代码区可能会被放在堆和栈的下方来防止堆和栈的覆写溢出。

Initialized Data Segments 初始化的数据区

初始化的数据区存储了所有的初始化了的全局的,静态的,常量的,外部的变量。这些变量没有在函数内部定义或者是以静态的方式在函数内部定义了,比如下面两种情况:

int val = 3;
char string[] = "Hello World";

这些变量最初是保存在只读内存中(Text/Code Segment 文本/代码区中),然后被拷贝到了初始化的数据区。

Uninitialized Data Segments 未初始化的数据区

未初始化的数据区,又称作BSS (Block Started by Symbol),这个区一般紧连着初始化的数据区,用来保存所有的初始化为0的全局变量和静态变量,或者没有初始化,比如 static int i;将会存在BSS中。BSS段属于静态内存分配。

Stack Segment 栈区

栈区是紧连着堆区的,堆和栈的增长方向相反,当堆和栈的指针重合时,此时内存被耗尽。栈区是以后进先出(LIFO)的机制运行的,通常在内存的高地址处。当一个函数被调用时,该函数的返回地址和调用者的环境信息被保存在栈中,新调用的函数再在栈上开辟空间保存自动和临时变量,这就是递归函数的运行机制。当一个递归函数调用它本身时,一个新的栈格被使用,所以这些变量不会跟上次递归的变量相互干扰。栈区主要保存一些局部变量。

  • 每个线程都有自己专属的栈

  • 栈的最大尺寸固定,超出则引起栈溢出

  • 变量离开作用域后栈上的内存会自动释放

Heap Segment 堆区

堆区主要用来动态分配内存。通过malloc, realloc和free来管理。堆区被所有线程,公用库,动态加载模块所共享。

Stack and Heap 堆和栈的区别

在和计算机内存打交道时,我们一定会碰到堆和栈,这两个东西很容易搞混,那么现在就来梳理一下二者的关系。

栈是用来静态分配内存的而堆是动态分配内存的,它们都是存在于计算机内存之中。

栈的分配是在程序编译的时候完成的,直接存储在内存中,接触内存很快。栈是后进先出的顺序,最后被申请的块最先被释放,这样就很容易跟踪到栈,释放栈的过程简单到仅仅是移动下指针就能完成。

堆的分配是在程序运行时完成的,分配速度较为缓慢,但是堆的可用空间非常的大。堆中的元素相互之间没有关联,各自都可以被任何时候随机访问。我们可以任何时候申请和释放一块内存,这样会使得我们很难随时随地追踪到堆中某块位置被分配了还是被释放了。

当你知道在编译前需要分配多少数据时且数据量不是很大时可以使用栈。如果不知道在运行时需要多少数据那么就该使用堆。

在多线程的程序里,每个线程都有其自己独立的栈,它们都共享一个堆。栈是面向线程的而堆是面向进程的。

程序、可执行文件与进程空间映射

... ...

参考:

  1. C Memory Layout C语言中的内存布局
  2. Stack and Heap 堆和栈的区别
  3. C语言和内存
  4. C语言的代码内存布局具体解释

相关文章

  • C语言基础-内存布局(Memory Layout)

    计算机中的内存是分区来管理的,程序和程序之间的内存是独立的,不能互相访问,比如QQ和浏览器分别所占的内存区域是不能...

  • Objective-C 引用计数的原理和内部实现

    背景 - 内存管理 Objective-C 建立在 C 语言的基础上。C 语言程序的内存布局主要包括: 栈:由编译...

  • 进程内存布局(Linux Memory Layout of a

    > text segment :这是由 C P U执行的机器指令部分 > Initialized data seg...

  • 进程内存布局(Linux Memory Layout of a

    传送门:https://www.jianshu.com/p/0cd8522b9598[https://www.ji...

  • C语言内存布局

    C语言内存布局规律 代码段 存放程序执行代码,这部分区域大小在程序运行前就已经确定,并且通常为只读权限,也有可能包...

  • Objective-C 内存管理基础

    前言 之前的两篇拙文C语言-内存管理基础、C语言-内存管理深入 介绍了关于C语言在内存管理方面的相关知识。但是对于...

  • Objective-C内存布局

    对象(object)即一块内存,本文要探讨的是一个Objective-C对象在内存的布局(layout)问题,一个...

  • C语言的malloc

    为什么C语言要有malloc malloc就是memory allocate动态分配内存,malloc的出现时为了...

  • C语言的内存布局

    C语言编程程序的内存如何布局 C语言程序连接过程中的特性和常见错误 C语言程序的运行方式 一:C语言程序的存储区域...

  • C语言程序内存布局

    C语言笔记之02-C语言程序内存布局 我们知道C语言的编译过程分为:预处理-编译-汇编-链接-生成可执行文件,而这...

网友评论

    本文标题:C语言基础-内存布局(Memory Layout)

    本文链接:https://www.haomeiwen.com/subject/ucqkictx.html