C语言的内存布局
目录:
一、C语言的内存布局规律
二、代码段
三、数据段
四、BSS段
五、堆
一、C语言的内存布局规律
C语言的内存布局,正式讲解之前先看一段代码。
#include <stdio. h>
#include <stdio. h>
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 _var静态变量(未初始化)
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 <stdio. h>
int global uninit var = 520 ;
int main(void)
static int num = 880 ;
char *str = "FishC" ;
return 0 ;
一个程序的本质是由text段,data段和bss段三个组成
五、堆
堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩展或缩小。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上;当利用free等函数释放内存时,被释放的内存从堆中被剔除。
- 大家平时可能经常听到堆栈这个词,一般指的就是这个栈。栈是函数执行的内存区域,通常和堆共享同一片区域。
- 堆和栈的区别
申请方式:
-堆由程序员手动申请-栈由系统自动分配
释放方式:
-堆由程序员手动释放-栈由系统自动释放
生存周期:
-堆的生存周期由动态申请到程序员主动释放为止,不同函数之间均可自由访问
-栈的生存周期由函数调用开始到函数返回时结束,函数之间的局部变量不能互相访问
- 发展方向:
-堆和其它区段一样,都是从低地址向高地址发展
-栈则相反,是由高地址向低地址发展
验证堆实验代码1:
#include <stdio. h>
#include <stdlib. h>
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<stdio . h>
#include <stdio. h>
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;
}
