动态内存分配,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