首页 > 系统相关 >C语言 内存布局

C语言 内存布局

时间:2023-10-18 13:44:12浏览次数:33  
标签:int 布局 C语言 test 内存 STR printf var t%

GCC编译

预处理->编译->汇编->链接

预处理:头⽂件包含、宏替换、条件编译、删除注释...
编译:主要进⾏词法、语法、语义分析等,检查⽆误后将预处理好的⽂件编译成汇编⽂件...
汇编:将汇编⽂件转换成 ⼆进制⽬标⽂件...
链接:将项⽬中的各个⼆进制⽂件+所需的库+启动代码链接成可执⾏⽂件...

内存布局

当我们运行程序时,可加载到 RAM 中。如下是一个内存布局图。
image

示例代码

#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

/* memory layout test */
/* #define STR(s) #s */
static int u_s_g_var_a; /* 未初始化静态全局变量a 存放在bss段 */
static int i_s_g_var_b = 10; /* 已初始化静态全局变量b 存在在data段 */

static int *u_s_g_var_p;
static int *i_s_g_val_p = &u_s_g_var_a;

int u_g_var_c; /* 未初始化全局变量c */
int i_g_var_d = 10; /* 已初始化全局变量d */

const int u_g_c_var_e; /* const 修饰未初始化全局常量 */
const int i_g_c_var_f = 10; /* const 修饰初始化全局常量 */

void func_test(void)
{
    printf("func\n");
}

int memory_layout_test(void)
{
    int l_var_a;
    int l_var_b = 10;
    int *l_var_c = NULL;
    int *l_var_d = NULL;
    static int u_s_l_var_e;
    static int i_s_l_var_f = 10;
    const int u_l_c_var_g;
    const int i_l_c_var_h = 10;
    char *l_var_s = "Hello World";
    char l_var_arr[] = "Hello World";
    const int *l_p_a =  &l_var_a;   /* 常量指针 */
    int * const l_p_b = &l_var_b;       /* 指针常量 */
    const int * const l_p_c =  &i_l_c_var_h;    /* 指向常量的常指针 */
    int *l_var_aa = (int *)alloca(sizeof(int) * 4); /* 从栈分配内存 */
		static int *i_s_l_var_p = &u_g_var_c;

    printf("-----------------------------------------------------\n");
    printf("栈区\n");
    printf("%s\t\t%p\n", STR(l_var_aa), l_var_aa);
    printf("%s\t\t\t%p\n", STR(l_var_a), &l_var_a);
    printf("%s\t\t\t%p\n", STR(l_var_b), &l_var_b);
    printf("%s\t\t%p\n", STR(&l_var_c), &l_var_c);
    printf("%s\t\t%p\n", STR(&l_var_d), &l_var_d);
    printf("%s\t\t%p\n", STR(u_l_c_var_g), &u_l_c_var_g);
    printf("%s\t\t%p\n", STR(i_l_c_var_h), &i_l_c_var_h);
    printf("%s\t\t%p\n", STR(&l_var_s), &l_var_s);
    printf("%s\t\t\t%p\n", STR(&l_p_a), &l_p_a);
    printf("%s\t\t\t%p\n", STR(&l_p_b), &l_p_b);
    printf("%s\t\t\t%p\n", STR(&l_p_c), &l_p_c);
    printf("%s\t\t%p\n", STR(l_var_arr), l_var_arr);


    l_var_c = (int *)malloc(sizeof(int) * 4);
    l_var_d = (int *)malloc(sizeof(int) * 4);
    printf("-----------------------------------------------------\n");
    printf("堆区\n");
    printf("%s\t\t\t%p\n", STR(l_var_c), l_var_c);
    printf("%s\t\t\t%p\n", STR(l_var_d), l_var_d);

    printf("-----------------------------------------------------\n");
    printf("bss区\n");
    printf("%s\t\t%p\n", STR(u_s_g_var_a), &u_s_g_var_a);
    printf("%s\t\t%p\n", STR(u_g_var_c), &u_g_var_c);
    printf("%s\t\t%p\n", STR(u_s_l_var_e), &u_s_l_var_e);
    printf("%s\t\t%p\n", STR(u_g_c_var_e), &u_g_c_var_e);
    printf("%s\t\t%p\n", STR(&i_s_l_var_p), &i_s_l_var_p);
    printf("%s\t\t%p\n", STR(&u_s_g_var_p), &u_s_g_var_p);
    printf("%s\t\t%p\n", STR(&i_s_g_val_p), &i_s_g_val_p);

    printf("-----------------------------------------------------\n");
    printf("data区\n");
    printf("%s\t\t%p\n", STR(i_s_g_var_b), &i_s_g_var_b);
    printf("%s\t\t%p\n", STR(i_g_var_d), &i_g_var_d);
    printf("%s\t\t%p\n", STR(i_s_l_var_f), &i_s_l_var_f);

    printf("-----------------------------------------------------\n");
    printf("text区\n");
    printf("常量\n");
    printf("%s\t\t%p\n", STR(i_g_c_var_f), &i_g_c_var_f);
    printf("%s\t\t\t%p\n", STR(l_var_s), l_var_s);

    printf("代码\n");
    printf("%s\t%p\n", STR(memory_layout_test), memory_layout_test);
    printf("%s\t\t%p\n", STR(func_test), func_test);

    free(l_var_c);
    l_var_c = NULL;
    free(l_var_d);
    l_var_d = NULL;
    return 0;
}

void main_test(void)
{
    printf("TEST ENTRY\n");
    printf("GNU libc version: %s\n", gnu_get_libc_version());
    memory_layout_test();
}

运行结果:

-----------------------------------------------------
栈区
l_var_aa                0xffcc5760
l_var_a                 0xffcc5784
l_var_b                 0xffcc5788
&l_var_c                0xffcc578c
&l_var_d                0xffcc5790
u_l_c_var_g             0xffcc5794
i_l_c_var_h             0xffcc5798
&l_var_s                0xffcc579c
&l_p_a                  0xffcc57a0
&l_p_b                  0xffcc57a4
&l_p_c                  0xffcc57a8
l_var_arr               0xffcc57b0
-----------------------------------------------------
堆区
l_var_c                 0x57f895b0
l_var_d                 0x57f895d0
-----------------------------------------------------
bss区
u_s_g_var_a             0x565d0050
u_g_var_c               0x565d004c
u_s_l_var_e             0x565d0058
u_g_c_var_e             0x565cca08
i_s_l_var_p             0x565d004c
&i_s_l_var_p            0x565d001c
&u_s_g_var_p            0x565d0054
&i_s_g_val_p            0x565d0018
-----------------------------------------------------
data区
i_s_g_var_b             0x565d000c
i_g_var_d               0x565d0010
i_s_l_var_f             0x565d0014
-----------------------------------------------------
text区
常量
i_g_c_var_f             0x565cca0c
l_var_s                 0x565cca15
代码
test_memory_layout      0x565c9b5e
func_test               0x565c9b33
参考链接:

https://en.wikipedia.org/wiki/Data_segment

https://en.wikipedia.org/wiki/Memory_segmentation

https://medium.com/@vikasv210/memory-layout-in-c-fe4dffdaeed6

https://github.com/gatieme/AderXCoding/tree/master/language/c/memory_layout

标签:int,布局,C语言,test,内存,STR,printf,var,t%
From: https://www.cnblogs.com/eezhijun/p/17695854.html

相关文章

  • C语言-结构体使用
    C语言-结构体使用#include<stdio.h>#include<stdlib.h>#include<string.h>//结构体/*结构体定义*/structPerson{ charname[20]; intage;};intmain(){/*结构体赋值*/ structPersonperson1={"Tom",20 }; printf("Name:%s,age:......
  • C语言-数组初始化方式
    C语言-数组初始化方式#include<stdio.h>#include<string.h>//数组初始化intmain(){ //方式1:{0} intarr1[3]={0}; for(inti=0;i<3;i++){ printf("arr1[%d]=%d\n",i,arr1[i]); } //方式2:for循环 intarr2[3]; for(inti=0;i<3;i++)......
  • IntellIJ Idea内存不足时怎么设置
    IntellIJIdea内存不足时怎么设置现在越来越多的人投入了IntellIJIdea的怀抱,它给我们的日常开发带来了诸多便利,但是由于对它的不熟悉,导致很多时候需要某些设置却不知道怎么去哪里设置,比如,在我们导入大项目时,IntellIJIdea向我们抛出了一个OutOfMemoryError......
  • 全面解析内存泄漏检测与修复技术
    本文分享自华为云社区《从源头解决内存泄漏问题:全面解析内存泄漏检测与修复技术》,作者LionLong。一、背景:什么是内存泄漏检测?1.1、内存泄漏产生原因内存泄漏是在没有自动gc的编程语言里面经常发生的问题;因为没有gc,所以分配的内存需要程序自己调用释放。其核心是调用分......
  • python 处理异步物化视图同时执行导致内存溢出问题
    python处理异步物化视图同时执行导致内存溢出问题一、前提:因为物化视图过多,同时物化视图到时间同时爆发,导致CPU爆满,所以采用datax自带的调度服务来执行python命令二、直接看代码:importpymysqlimportpymssqlimportdatetimeimporttimeclassMaterialized_plan:d......
  • C语言部分学习知识记录
    导包#include时候使用<>和""的区别://<filename.h>->去系统存放头文件的位置找.h文件//"filename.h”->去当前目录寻找头文件,如果没找到再去系统存放头文件的位置找.h文件main函数中参数意义//intargc->从命令行传入的参数个数//char*argv[]->存放参数的数组//char*env[......
  • 【C语言】数组指针
    【C语言】数组指针顾名思义,数组指针是指向数组的指针。例如,p是一个指向含有3个int元素的一维数组的指针:int(*p)[3];//圆括号的优先级更高,让p先与*结合再与[]结合用法:#include<stdio.h>//voiddisplay1(intp[][3])//等价下行写法voiddisplay......
  • qt如何隐藏布局
    布局本身无法被隐藏,但是控件可以被隐藏;可以通过将整个布局放入控件中,通过隐藏控件来隐藏整个布局;下面以软键盘为例: 这样设计↑; 运行这样的代码↑; 运行效果↑:......
  • 从内存使用角度的比较:Go vs Rust
    Go和Rust是最近几年非常火的语言,经常有人问到底该怎么选择,特别是谁更适合搭建网络后台服务,哪一个性能更好,稳定性更高。网络上Go和Rust的比较文章很多,大体上是做一个测试或写几段测试代码,根据运行的时长来比较哪个性能更好,但这种测试可能会陷入误区:1)比来比去,比的是网络IO,因为这种......
  • 初入c语言学习
        hello,我是一名大一新生,2023/8/1开始在视频上跟着学习c语言。回顾前两个月,我对c语言的认识已经不停留在一门高深莫测的技术,也让我逐渐清晰自己想要什么,当然,与此相对应的就是付出比在暑假期间更多学习时间的决心。    在学习前,因对c语言认识有限,或者说对计算机这......