=内存分布=======
1.什么是虚拟内存?物理内存?有什么关系?大小?
物理内存: 实际的内存存储空间 内存条 大小取决于内存条的大小
虚拟内存: 由系统根据物理内存映射出来的内存 大小由系统决定
关系: 虚拟内存由物理内存映射出来
2.虚拟内存,有哪些组成部分
初始化 栈 堆 数据段 代码段
3.程序为什么能够运行
查看可执行程序的结构
readelf -S 程序名
4.elf可执行程序的结构
[11] .init
初始化代码段(准备工作 ,只执行一次)
[14] .text
正文段(代码段 函数的代码都是放在这里的)
[16] .rodata
只读数据段(常量区 常量字符串) char *p = “hello”; char buf[] = "hello" ;
[25] .data
静态数据段(已初始化的数据)
[26] .bss
静态数据段(未初始化的数据)
动态数据段
堆和栈
建造计划
电影剧本
5.运行程序
a.固定大小
[11] .init
初始化代码段(准备工作 ,只执行一次)
[14] .text
正文段(代码段 函数的代码都是放在这里的)
[16] .rodata
只读数据段(常量区 常量字符串) char *p = “hello”; char buf[] = "hello" ;
[25] .data
静态数据段(已初始化的数据)
[26] .bss
静态数据段(未初始化的数据)
b.不固定
栈空间 — (局部变量定义 函数调用 系统分配)
堆空间 — (用户自己根据需求申请使用)
============================= 内存管理应用=============================
1.变量初始化
1.局部变量 存在于栈空间 ,如果不初始化 ,就是随机的
2.未初始化的全局变量 存在于.bss ,里面的数据会被清零
2.多文件编译
main.c fun.c
1.extern ,外部引用
外部函数的调用声明
如果使用的函数是其他文件的,一般需要使用extern进行声明
外部全局变量声明
如果使用的变量是其他文件的,一般需要使用extern进行声明
局部变量默认就是内部连接属性: 只能在定义它的文件(函数)中使用
全局变量默认就是外部连接属性: 可以在任意的文件中使用 前提 extern声明
2.static
修饰的是局部变量,将它存储的位置,放到静态数据段
修饰的是全局变量 改变变量的连接属性:外部–》内部
修饰的是函数 改变函数的连接属性:外部–》内部
注意:
1.修饰函数和全局变量时,就是把资源私有化只能在定义它们的文件中使用,其他文件用不了,
哪怕是使用extern 也没有用。
2.在其他函数中使用static修饰的局部变量
使用地址操作
应用 :比如 记录函数被调用的次数
3.静态数据
1.只能被初始化一次
2.尽量避免大量使用静态数据(全局变量 static修饰的局部变量)
1.会一直占用内存
2.共享资源,多个函数,多个线程都可以访问(可能会出现竞争关系)
====================堆和栈
1.相同点
1.大小随着申请随时变化
2.都是可以储存所有的数据类型
3.大小都有限制
堆空间 没有限制(系统)取决于物理内存
栈空间 有限制 固定大小 大概是8m
2.区别
1.大小
栈空间: 固定 8m左右
stack size (kbytes, -s) 8192
堆空间: 大小不同 取决于物理内存 具体使用多少由程序决定
2.使用方法
栈:
系统决定,作用域结束,会被系统释放掉
堆:
由程序员决定,从申请到释放(malloc free)
3.特性
栈:
先进后出 (递归函数)
堆:
普通的内存操作就可以,自由
3.堆空间的使用
1.申请堆空间
#include <stdlib.h>//头文件
在堆里申请一块size字节的连续内存,未初始化
void *malloc(size_t size);
参数
size 大小 单位:字节
返回值
成功 申请到的内存首地址
失败 NULL
在堆里面申请n块size大小的连续内存,清空为0
void *calloc(size_t nmemb, size_t size);//n*size
参数
nmemb: nmemb个内存块
size : 每个内存块的大小 单位:字节
返回值
成功 申请到的内存首地址
失败 NULL
calloc(5,sizeof(int));
//拓展已经申请到的堆空间
void *realloc(void *ptr, size_t size);
参数 :
ptr malloc或者calloc的返回值 申请到的内存首地址
size 新的扩展后堆空间大小
返回值:
扩展后的内存首地址 (可能是原来的也可能是新的地址)
2.使用堆空间
获取到申请的内存首地址后,根据要存储的数据类型进行强转
int *p = (int *)malloc(4);
*p = 20;
printf("*p %d\n",*p);
3.释放堆空间
void free(void *ptr);