C语言内存分布

动态内存分配,C语言动态内存分配详解
C语言知识总结(十一)内存管理
C语言内存分布图

在这里插入图片描述

代码段:const常量,字符串常量
数据段:已初始化全局变量、已初始化全局静态变量、局部静态变量、常量数据
BSS段:未初始化全局变量、未初始化全局静态变量
栈:局部变量、函数参数
堆:动态内存分配

栈(stack)是从高字节向低字节分配内存的,堆(heap)是从低字节向高字节分配内存的
在这里插入图片描述

通过下面的一段代码,应该可以深刻的理解C语言的内存分布了。
#include <stdio.h>  
#include <stdlib.h>
#include <string.h>
const int    g_A = 10;         //rodata段  
const int    g_A_A;            // bss段
int          g_B = 20;         //数据段  
static int   g_C = 30;         //数据段  
static int   g_D;              //BSS段  
int          g_E;              //BSS段
int          g_F;              //BSS段
char        *p1;               //BSS段  
  
int main( )  
{  
    const int g_A_B;   //栈
    const int g_A_C;   // 栈
    int local_A;            //栈  
    int local_B;            //栈  
    static int local_C = 0; //数据段  
    static int local_D;     //数据段  
     
    char *p3 = "123456";     //"123456"在代码段,p3在栈上  
	char p4[] = "12345";     //"12345"和p4都是在栈上,这里会产生一个"12345"的副本,存在栈上
  
    p1 = (char *)malloc(10);      //堆,分配得来得10字节的区域在堆区  
    strcpy(p1, "123456");         //123456{post.content}放在常量区,编译器可能会将它与p3所指向 的"123456"优化成一块  
  
    printf("hight address\n");  
    printf("-------------栈--------------\n");  
    printf("栈,    局部变量,                           g_A_B,     addr:0x%08x\n", &g_A_B);
    printf("栈,    局部变量, (后进栈地址相对g_A_B低)     g_A_C,     addr:0x%08x\n", &g_A_C); 
    printf("栈,    局部变量,(后进栈地址相对g_A_C低)      local_A, addr:0x%08x\n", &local_A);  
    printf("栈,    局部变量,(后进栈地址相对local_A低)   local_B, addr:0x%08x\n", &local_B);
    printf("栈,    局部变量,(后进栈地址相对local_B低)   p3, addr:0x%08x\n", &p3); 
	printf("栈,    局部变量,(后进栈地址相对p3低)        p4, addr:0x%08x\n", p4);
	printf("栈,    局部变量,(后进栈地址相对p3低)   &p4, addr:0x%08x\n", &p4);
    printf("-------------堆--------------\n");  
    printf( "堆,    malloc分配内存,             p1,      addr:0x%08x\n", p1);  
    printf("------------BSS段------------\n");  
    printf("bss段,全局初始化变量, 只读const,  g_A_A,     addr:0x%08x\n", &g_A_A);
    printf("BSS段, 全局变量,       未初始化    g_E,     addr:0x%08x\n", &g_E); 
    printf("BSS段, 全局变量,(和上面的那个全局变量地址临近)       未初始化    g_F, addr:0x%08x\n", &g_F);
    printf("BSS段, 全局变量        未初始化                              p1, addr:0x%08x\n", &p1); 
    printf("BSS段, 静态全局变量,   未初始化,(下面三个静态变量地址临近)   g_D, addr:0x%08x\n", &g_D);  
    printf("BSS段, 静态局部变量,   初始化,     local_C, addr:0x%08x\n", &local_C);  
    printf("BSS段, 静态局部变量,   未初始化,   local_D, addr:0x%08x\n", &local_D);  
    printf("-----------数据段------------\n");  
    printf("数据段,全局变量,       初始化      g_B,     addr:0x%08x\n", &g_B);  
    printf("数据段,静态全局变量,   初始化,     g_C,     addr:0x%08x\n", &g_C);  
    printf("-----------代码段------------\n");  
    printf("rodata段,全局初始化变量, 只读const,  g_A,       addr:0x%08x\n", &g_A); 
	printf("代码段,指向字符串常量,             p3,        addr:0x%08x\n", p3);
    printf("low address\n");  
    return 0;  
}  

输出结果如下:

hight address
-------------栈--------------
栈,    局部变量                          g_A_B,     addr:0x0061fe1c
栈,    局部变量,(后进栈地址相对g_A_B低)    g_A_C,     addr:0x0061fe18
栈,    局部变量,                          local_A, addr:0x0061fe14
栈,    局部变量,(后进栈地址相对local_A低)   local_B, addr:0x0061fe10
栈,    局部变量,(后进栈地址相对local_B低)   p3, addr:0x0061fe08
栈,    局部变量,(后进栈地址相对p3低)        p4, addr:0x0061fe02
栈,    局部变量,(后进栈地址相对p3低)   &p4, addr:0x0061fe02
-------------堆--------------
堆,    malloc分配内存,             p1,      addr:0x00192410
------------BSS段------------
BSS段, 全局变量,       未初始化    g_E,     addr:0x0040797c
BSS段, 全局变量,(和上面的那个全局变量地址临近)       未初始化    g_F, addr:0x00407980
BSS段, 全局变量        未初始化                              p1, addr:0x00407970
BSS段, 静态全局变量,   未初始化,(下面三个静态变量地址临近)   g_D, addr:0x00407030
BSS段, 静态局部变量,   初始化,     local_C, addr:0x00407034
BSS段, 静态局部变量,   未初始化,   local_D, addr:0x00407038
-----------数据段------------
数据段,全局变量,       初始化      g_B,     addr:0x00403010
数据段,静态全局变量,   初始化,     g_C,     addr:0x00403014
-----------代码段------------
代码段,全局初始化变量, 只读const,  g_A,       addr:0x00404000
代码段,全局初始化变量, 只读const,  g_A_A,     addr:0x00407978
代码段,指向字符串常量,             p3,        addr:0x00404004
low address

解释说明如下:local_A,local_B,p3,p4是局部变量,所以分配在栈区,且栈区地址分配是从高到低,而且local_B是int类型的,所以占四个字节,所以和local_B相差四个字节,p3是一个指针,在64位机器中占8个字节,所以和local_B差8个字节,p4是一个数组名,是一个sizeof为6的数组,所以占6个字节,所以和p3相差6个字节。 p1, p3, p4取地址和不取地址的区别要注意,对于p1和p3来说,本身是指针,就代表指向的那块内存的地址,所以p1指向malloc的内存,是在堆区 ,p3指向字符串常量,是在代码段。p4是数组名,即数组首元素地址,因为其等于一个字符串常量,就是有一个副本,存在栈区,所以,p4在栈区。取地址之后,代表这个变量本身存在那个区,所以&p1是在bss段,p3和p4都是局部变量,当然&p3和&p4都是在栈区。对于数组名来说,p4等于&p4。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值