二.内存管理
mmap/munmap
brk/sbrk
malloc/free/calloc/realloc
new/new[]/delete/delete[]
STL内存管理Allocator
智能指针
1.认识各种不同的内存
代码区
全局区
局部区
堆区
实验1:
直观查看各个内存段。
/proc/$PID/maps文件动态映射进程的内存结构
/proc/$PID在进程结束以后,自动删除.
1000 =4Kbyte=4096byte=1page
注意:/proc文件系统暴露系统内核的相关信息。
Linux中程序代码空间地址永远在08048000
0-3G应用程序使用的空间
3G-4G内核init使用的空间3G-3G+8M
实验2:
体会各种变量在内存中的位置
实验3:
栈地址的变化(从大变小)
堆地址的变化(从小变大)
问题:
栈分配空间是实际大小
堆分配的空间是实际大小+12字节
2.malloc与new分配空间的差别
2.1.malloc/new怎么分配空间(虚拟内存)
用户申请一个空间,系统查找大块没有使用的空闲的地址.
并且关联一个物理空间(映射)
实验
体会虚地址/虚拟内存的概念
结论:
每个进程都有一个虚拟的从0-4G地址。
平面内存.flat memory
虚拟内存映射物理内存采用
段页管理
段:把地址转换为线性地址
页:完成实际物理映射,一般为了处理碎片内存,页分成3-4级
2.2.malloc/new对分配的空间怎么管理?
实验:
体会malloc对内存是有管理的。
a.栈是栈结构管理,malloc采用堆的方式管理。
堆的管理采用是链表容器来管理。
链表的节点:上一个内存节点地址
下一个内存节点地址
内容内存空间
内存大小
b.malloc按页申请空间
2.3.堆内存访问的规则:
不允许的访问:
段错误访问(能否访问)
非法访问 (该否访问)
识别是否非法访问破坏内存管理结构。
识别什么情况下会段错误。
不要胡乱使用指针运算。
+n -n +=n -=n ++ -- []
if(p) *p
2.4.C++ 与C内存操作的区别
相同点:
new :malloc calloc
delete :free realloc
new[] :calloc malloc
delete[]:free
new() :realloc (replacement alloc)
区别点:
delete 调用一次析构器
delete[] 调用多次析构器
new调用一次构造器
new[]调用多次构造器
int *a=new int[30];
delete a; ~a(),free(a);
delete[] a; ~a[0]() ~a[1]()...,free(a);
free /delete /delete[]区别
不调用/调用一次/调用多次
3.C是否可以像栈一样来自己管理内存。
brk/sbrk
练习:
1-10000之间所有孪生素数
孪生素数:连个之间差的绝对值<=2
1.函数说明:
int brk(void *p);
作用:
分配/释放空间
参数:
void*p指定有效地址末尾范围
返回:
0:
内存分配释放成功
-1或者ENOMEM:
内存分配失败
void *sbrk(intptr_t increment)
作用:
分配释放空间
参数:
要分配空间大小
返回:
分配空间的首地址
2.理解brk/sbrk函数
malloc在后台维护一个数据结构链表。
brk/sbrk在后台维护数据:开始地址、结束地址
sbrk(0)返回一个开始地址.地址在页首:4k的倍数
实验:
使用sbrk返回空闲的首地址!但不映射物理空间
sbrk参数可以
>0:分配空间,返回首地址
=0:不动,返回首地址
<0:释放空间,返回首地址
建议不要使用sbrk释放空间.
建议使用sbrk返回首地址。而是使用brk改变末尾地址实现分配与释放
案例:
查找1-10000之间所有素数,保存到内存,查找完毕
打印所有素数。释放空间
注意:分配空间
使用空间
释放空间
问题:
int a[20][20];
a[10] -a[1];返回个数
int *p=new int[20][20];
p[10]-p[1];返回地址字节数