开发者学堂课程【你的第一门 C 语言课:C 语言的内存布局】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/444/detail/5488
C 语言的内存布局
目录:
一、C 语言的内存布局规律
二、代码段
三、数据段
四、BSS 段
五、堆
一、C 语言的内存布局规律
C 语言的内存布局,正式讲解之前先看一段代码。
#include
#include
int global_ uninit_ var;
int global init var1 = 520;
int global init var2 = 880;
//首先三个全局变量,初始化。
void func (void) ;
void func (void)
{
;//空语句。
}
int main(void)
{
int local var1;
int local var2;
//两个局部变量。
static int static_uninit_var ;
static int static_init_var = 456 ;
//两个静态变量。
char *str1 = "I love FishC.com!";
char *str2 = "You are right!";
//两个字符串。
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_init_var -> %p\n", &static_init_var) ;
printf("addr of static_uninit_var -> %p\n"&static_uninit_ var) ;
printf("addr of global_uninit_var -> %p\n", &global_ uninit_ var) ;
printf("addr of malloc_var ->%p\n",malloc_var) ;
printf("addr of local_var1 ->%p\n", &local_var1) ;
printf("addr of local var2 -> %p\n", &local_var2) ;
return 0;
}
C 语言内存布局规律
内存地址由高到低为:
local_var 局部变量
local_var 局部变量
malloc _var 动态申请的内存空间
global_init_var 全局变量(未初始化)
static _uninit _va r静态变量(未初始化)
static _uninit _var 静态变量(初始化)
global_init_var2 全局变量(初始化)
global_init_var1 全局变量(初始化)
str2 字符串常量
str1 字符串常量
func 函数
二、代码段
代码段 ( Text segment) 通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读。
在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
三、数据段
数据段 (Initialized data segment) 通常用来存放已经初始化的全局变量和局部静态变量。
四、BSS 段
BSS 段( Bss segment/Uninitialized datasegment) 通常是指用来存放程序中未初始化的全局变量的一块内存区域 BSS 是英文 Block Started by Symbol 的简称,这个区段中的数据在程序运行前将被自动初始化为数字0。
实验代码:
#include
int global uninit var = 520 ;
int main(void)
static int num = 880 ;
char *str = "FishC" ;
return 0 ;
一个程序的本质是由text段,data段和bss段三个组成
五、堆
堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩展或缩小。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上;当利用free等函数释放内存时,被释放的内存从堆中被剔除。
- 大家平时可能经常听到堆栈这个词,一般指的就是这个栈。栈是函数执行的内
存区域,通常和堆共享同一片区域。
- 堆和栈的区别申请方式:
-堆由程序员手动申请-栈由系统自动分配释放方式:
-堆由程序员手动释放-栈由系统自动释放
- 生存周期:-堆的生存周期由动态申请到程序员主动释放为止,不同函数之间均可
自由访问-栈的生存周期由函数调用开始到函数返回时结束,函数之间的局部变量不能互相访问
- 发展方向:
-堆和其它区段一样,都是从低地址向高地址发展
-栈则相反,是由高地址向低地址发展
验证堆实验代码1:
#include
#include
int *func (void )
{
int *ptr = NULL ;
ptr= (int * malloc(sizeof(int)) ;
if (ptr == NULL)
{
exit(1) ;
}
*ptr = 520;
return ptr ;
}
int main(void )
{
int *ptr = NULL ;
ptr = func() ;
printf("%d\n",*ptr) ;
free(ptr);
return 0 ;
}
堆实验代码2:
#include
#include
int main(void)
{
int *ptr1 = NULL ;
int*ptr2 = NULL ;
ptr1 = (int * )malloc (sizeof(int)) ;
ptr2 = (int * )malloc (sizeof(int));
printf("stack:%p ->%p\n", &btr1, &ptr2);
printf("heap:%p ->%p\n", &ptr1, &ptr2) ;
ptr1 = (int *)realloc(ptr1,2 * sizeof(int))
printf("heap: %p -> %\n,ptr1, ptr2) ;
return 0;
}