堆栈概念
栈:系统自动管理的内存区
1,临时变量的内存在栈里面(函数内部定义的变量)
2,内存地址自上往下
3,从高地址开始往低地址申请内存
堆:手动申请及管理的内存区域
1,通过malloc系列函数及free函数去进行申请及释放的
2,如果你不释放,永远占着内存
3,内存的申请及地址从下往上去申请的
void *:万能同配的指针
他可以兼容所有类型的指针,
堆操作函数
malloc:
#include <stdlib.h>
void *malloc(size_t size);
malloc:
size:申请多大的内存,以字节为单位
void *calloc(size_t nmemb, size_t size);
calloc:
nmemb:申请几块内存
size:每块内存多大
void *realloc(void *ptr, size_t size);
realloc:意义:重置申请内存的大小
ptr:重置哪块内存,把这块内存地址给他
size:重置成为多大
void free(void *ptr);
free:
释放申请的堆内存
注意:该函数不会清空里面的内容
返回值:
如果返回值为NULL,则代表失败
static
由static修饰的变量会有什么作用:
1,由static修饰的全局变量或函数具有文件作用域(当前文件可以用,其他文件用不了)
2,由static修饰的局部变量,可以具有全操作权限,局部变量只在编译的时候初始化一次
之后的调用,再也不初始化了
3,改变局部变量的存储区域
存储周期
静态存储周期:
全局变量和static修饰的变量
在程序编译的时候已经规划好内存,直接登记在程序代码里面,
一直作用在代码运行中,伴随代码终身
自动存储:
局部变量(没有static)
它的内存存在在栈里面,由系统自动管理
动态存储:
由malloc等堆函数申请的内存
1,没有别名
2,内存在堆里面
register关键字
1,如果你的数据需要大量的运算及读写的时候,使用这个关键字
2,它只是尝试帮你申请寄存器,如果申请不到,变量内存放在栈里面
3,只能在函数内部使用,不能全局
4,如果函数调用结束,寄存器也会被释放掉
5,register申请的变量必须是CPU支持的
volatile关键字
特点:防止优化:
1,防止编译优化变量
2,实时的检查内存
程序段落说明
.bss:未初始化段落
由static修饰或者是全局的变量,未给其赋初始值的变量,内存存放的区域
.data:初始化段落
由static修饰或者是全局的变量,已经赋初始值的变量,内存存放的区域
.rodata:常量存放区
常量存放的地区
.init:程序代码初始化模块
存放着代码的起始模块内容
.fini:程序代码退出模块
存放着释放资源的模块代码
.text:该section包含了程序的可执行指令
特殊内存分析资料,作为了解
1..bss,该section包含了在内存中的程序的未初始化的数据,当程序开始运行时,
系统将用0来初始化该区域。该section不占用文件空间,
该section type = SHT_NOBITS;
2..comment,该section包含了版本控制信息;
3..data和.data1,该section包含了在内存中的程序的初始化数据;
4..debug,该section包含了符号调试信息,其中内容没有硬性规定;
5..dynamic,该section包含了动态链接信息,
该section属性将包含SHF_ALLOC比特位,
而SHF_WRITE比特位是否为1取决于处理器;
6..dynstr,该section包含了用于动态链接的字符串,通常是符号表项名称字符串;
7..dynsym,该section包含了动态链接符号表;
8..fini,该section包含了用于终止进程可执行指令代码;
9..got,该section包含了全局偏移表;
10..hash,该section包含了符号hash表;
11..init,该section包含了用于初始化进程的可执行代码,
也就是说,当一个程序开始运行的时候
系统将会执行在该section中的代码,
然后才会调用程序的入口点(对于C程序而言就是main);
12..interp,该section包含了程序解释其的路径;
13..line,该section包含了符号调试信息的行号,
其用于描述程序源代码和机器码之间的相应关系;
14..note,该section包含了供应商及程序兼容信息等;
15..plt,该section包含了程序链接表;
16..relname和.relaname,该section包含了relocation信息,
该section的属性包括了SHF_ALLOC比特位
通常,name为将要被重组的section的名称,
例如如果要重组.text,那么名称就为.rel.text或者.rela.text;
17..rodata和.rodata1,该section包含了只读数据,通常进程中的不可写段,
例如Program Header;
18..shstrtab,该section包含了section名称;
19..strtab,该section包含了符号表项名称字符串,
如果文件包含了一个可加载的并且包含了符号字符串表的segment
则section的SHF_ALLOC比特位属性将被设置;
20..symtab,该section包含了符号表,如果文件包含了一个可加载的
并且包含了符号表的segment
则section的SHF_ALLOC比特位属性将被设置;
21..text,该section包含了程序的可执行指令。
虽然上面的例子文件中,对于text和data段而言,
但是:
1.text的第一个页面包含了ELF header,program header table以及其他的信息;
2.text的最后一个页面包含了data的开始部分数据的拷贝;
3.data的第一个页面包含了text的末尾数据的拷贝;
4.data的最后一个页面也许包含了和运行进程不相关的文件信息;
理论上讲,系统对待每个段的内存权限都是相互独立的。
段地址不得不调整来确保地址空间中的每个逻辑页面都有自己的权限;
在上面的例子中,包含了text结尾和data开始的区域将要被映射两次:
一次就是包含了text和data开始部分,
另一个就是text末尾部分和data;
data段的末尾还需要对为初始化数据的特殊处理,系统通常将其清零。