首页 C语言 程序的内存布局
文章
取消

C语言 程序的内存布局

此篇博客仍在整理中,内容质量及排版比较一般,还请见谅

内存布局

程序的内存布局

  • text代码段,存放程序的二进制代码、字面量(整数常量浮点常量字符常量字符串字面值枚举常量),该区域的大小在编译期间即可确定,在运行期间通常是只读的;

  • data存放已初始化且初始值非零的静态变量的全局数据段,静态变量在进程启动时被依次赋值,在进程结束时被系统释放,该区域的大小在编译期间即可确定,在运行期间是可读写的,但是整个 data 段的大小是固定的;

  • bss存放未初始化或初始值为零的静态变量的全局数据段,进程启动时会将该区域全部赋予 0 值,在进程结束时被系统释放,该区域的大小在编译期间即可确定,在运行期间是可读写的,但是整个 bss 段的大小是固定的;

  • heap堆区存放进程在运行期间动态申请的内存段,大小是不固定的,可动态扩张和缩减,使用 malloc 等函数分配的内存就在堆上,使用完后可以使用 free 函数来主动释放申请的内存,如果不释放,则在进程结束时被系统自动释放;

  • stack栈区存放函数的局部变量、函数的参数等值,每个函数栈帧的大小在编译期间是确定的,但是整个栈区的大小是不定的,不过操作系统对于每个栈的大小是有限制的,在 Linux 中一般为 8192 KB,也就是 8 MB,如果需要可以适当调高(使用 ulimit 命令)。

在多线程环境中:

  • textdatabssheap都是线程间共享的,如果对该区域的数据的访问顺序敏感,则需要采取相应的措施,如使用互斥锁,来避免出现脏数据问题;

  • stack是每个线程私有的,每个线程都会有一个独立的 stack 区域,每个 stack 区域都拥有一样的大小限制(即操作系统对栈的大小限制)。

实例说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int i1; // 变量 i1 位于 bss
int i2 = 0; // 变量 i2 位于 bss

char ch = 'A'; // 变量 ch 位于 data,值 'A' 位于 text

// 变量 str1 位于 data,值 "www.zfl9.com\0" 位于 text
char *str1 = "www.zfl9.com";
// 变量 str2 位于 data,值 "www.zfl9.com\0" 位于 text (与 str1 指向的是同一个字符串)
char *str2 = "www.zfl9.com";

int main(void) {
    static int st_i; // 变量 st_i 位于 bss
    static char st_c = 'X'; // 变量 st_c 位于 data,值 'X' 位于 text

    int au_i; // 变量 au_i 位于 stack

    // 变量 str3 位于 stack,分配的内存位于 heap
    char *str3 = (char *)malloc(sizeof(char) * 20);
    // 变量 str4 位于 stack,值 "www.google.com\0" 位于 text
    char *str4 = "www.google.com";
    // "www.google.com\0" 位于 text,并且与 str4 指向的是同一个字符串
    strcpy(str3, "www.google.com");

    free(str3);
    return 0;
}
本文由作者按照 CC BY 4.0 进行授权

C语言 变量与数据类型

C语言 分支与循环