C语言内存布局

#include
#include

int global_uninit_var;     //全局未初始化变量
int global_init_var1=1;    //全局初始化变量
int global_init_var2=2;    //全局初始化变量

int static_global_uninit_var;            //静态全局变量(未初始化)
int static_global_init_var=3;     //静态全局变量(初始化)

void func(void);
void func(void)
{
    ;
}

int main(int argc,char** argv)
{
    int local_init_var=1;   //局部变量初始化
    int local_var1;    //局部变量1
    int local_var2;    //局部变量2

    static int static_local_uninit_var;   //静态局部未初始化变量
    static int static_local_init_var=10;  //静态局部初始化变量

    char* str1="hello";             //字符串常量1
    char* str2="world";             //字符串常量2

    int* malloc_var=(int*)malloc(sizeof(int)); //动态申请内存

    printf("addr of func -> %p\n",                           func);
    printf("addr of str1 -> %p\n",               str1);
    printf("addr of str2 -> %p\n",               str2);
    printf("addr of global_init_var1 -> %p\n",       &global_init_var1);
    printf("addr of global_init_var2 -> %p\n",       &global_init_var2);
    printf("addr of static_global_init_var -> %p\n",     &static_global_init_var);
    printf("addr of static_local_init_var -> %p\n",      &static_local_init_var);
    printf("addr of static_local_uninit_var -> %p\n",    &static_local_uninit_var);
    printf("addr of global_uninit_var -> %p\n",          &global_uninit_var);
    printf("addr of static_global_uninit_var -> %p\n",       &static_global_uninit_var);
    printf("addr of malloc_var -> %p\n",             malloc_var);
    printf("addr of local_init_var -> %p\n",         &local_init_var);
    printf("addr of local_var1 -> %p\n",             &local_var1);
    printf("addr of local_var2 -> %p\n",             &local_var2);
    /*  
        以下各个地址从小到大排列
    addr of func -> 0x55bfc58bf189                          //函数
    addr of str1 -> 0x55bfc58c0008                          
    addr of str2 -> 0x55bfc58c000e                          //字符串常量
    addr of global_init_var1 -> 0x55bfc58c2010
    addr of global_init_var2 -> 0x55bfc58c2014              //全局变量(初始化)
    addr of static_global_init_var -> 0x55bfc58c2018        //静态全部变量(初始化)
    addr of static_local_init_var -> 0x55bfc58c201c         //静态局部变量(初始化)
    addr of static_local_uninit_var -> 0x55bfc58c2024       //静态局部变量(未初始化)
    addr of global_uninit_var -> 0x55bfc58c2028             //全局变量(未初始化)
    addr of static_global_uninit_var -> 0x55bfc58c202c      //静态全局变量(未初始化)
    addr of malloc_var -> 0x55bfc70402a0                    //动态申请的内存空间
    addr of local_init_var -> 0x7fff1fc55044                //局部变量(初始化)
    addr of local_var1 -> 0x7fff1fc55048                    //局部变量(未初始化)
    addr of local_var2 -> 0x7fff1fc5504c

     */

    return 0;
}

C语言内存布局规律

内存布局

代码段

存放程序执行代码,这部分区域大小在程序运行前就已经确定,并且通常为只读权限,也有可能包含一些只读变量,如字符串常量等。

数据段

通常用来存放已经初始化的全局变量和局部静态变量

BSS(Block Started by Symbol)段

通常用来存放程序中未初始化的全局变量和局部静态变量,这个区段中的数据在程序运行前被自动初始化为0

在linux系统下编辑以下代码test.c

#include

int main(int argc,char** argv)
{
    return 0;
}

使用以下命令编译生成test可执行文件

gcc test.c -o test

使用以下命令查看test所占内存情况

size test
size test

text为占用代码段大小,data为占用数据段大小,bss为占用BSS段内存大小

在代码中添加一个初始化的全局变量

#include

int global_uninit_var=1;

int main(int argc,char** argv)
{   
    return 0;
}

再次使用上面的命令重新编译执行并size test查看大小

size test

数据段为548个字节,多了4个字节,但为什么BSS少了四个字节?(求大神告知),证明初始化的全局变量存储于数据段,要验证其他变量存储区域,采用同样的方法。

存放进程运行中被动态分配的内存段,大小不固定,可动态扩展或缩小。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上,当利用free等函数释放内存时,被释放的内存从堆中被剔除。

栈时函数执行的内存区域,通常和堆共享同一片区域,如函数的参数、返回值都是放在栈里的。

堆和栈的区别

1.申请和释放方式

堆由程序员手动申请,手动释放
栈由系统自动分配,自动释放

2.生存周期

堆的声明周期由动态申请到程序员主动释放为止,不同函数之间可以自由访问

#include 
#include
int* func(void)
{
    int* ptr = NULL;
    ptr = (int*)malloc(sizeof(int));
    if (ptr == NULL)
    {
        printf("申请失败\n");
    }
    else
    {
        *ptr = 1;
    }
    return ptr;
}

int main(int argc, char** argv)
{
    int* ptr = NULL;

    ptr = func();

    printf("%d\n", *ptr);  //1  main函数可以访问到func函数中在堆中申请的内存,不建议,最好在哪个函数申请,就在那个函数释放
    
    free(ptr);

    return 0;
}

栈的生存周期由函数调用到函数返回时结束,函数之间的局部变量存在于栈上,不可互相访问

3.发展方向(不同的编译器和机器有可能不一样):

堆和其他区段都是从低地址向高地址发展
栈则相反,从高地址向低地址发展

堆和栈更仔细的区别可以参考http://c.biancheng.net/c/stack/

你可能感兴趣的:(C语言内存布局)