说起malloc,但凡对C/C++有点基础的人在编写代码的时候都用过。我们调用malloc接口分配一段连续的内存空间,不使用时使用free可以释放这段内存空间。这些我们都已经比较的熟悉了。但是你知道malloc背后的调用机制吗?
C语言程序员都知道,malloc只是C语言库标准提供的一个普通函数,我们实现的malloc和库函数比起来效率要低很多,但是可以通过编写一个简单的malloc来体现C库的精髓,我们实现的malloc和库的实现原理上市一致的。
一,malloc的定义:
根据标准C的定义,malloc的函数原型是这样的:
<span style="font-family:Microsoft YaHei;font-size:14px;">void* malloc(size_t size);</span>
函数要求如下:
- malloc函数分配的内存大小至少为size参数所指定的字节数。
- malloc的返回值是一个void类型的指针,我们必须强制转化为我们需要的类型的指针。
- 多次调用malloc所分配的地址不能有重叠部分,除非某次molloc所分配的地址被free释放掉了。
- malloc应该尽快的完成内存额分配并且返回。
- 实现malloc的同时实现calloc和realloc和free。
如果是子啊Linux环境下,可以使用
<span style="font-size:14px;">man malloc
</span>
查看malloc的具体定义。
二,Linux的内存管理
1.虚拟内存地址与物理内存地址的关系:
现代操作系统在处理内存地址时普遍的采用虚拟内存地址技术,什么事虚拟内存技术呢?
这种技术使每个进程“仿佛独享”一块2N字节的内存(N是机器的位数),例如在64位的操作系统下,每个进程的虚拟内存空间是264B。这种虚拟内存空间的作用是简化程序的编写并且方便操作系统对进程之间的隔离管理。
虚拟内存技术是由MMU和页表构成的,MMU是一种映射算法,它从虚拟内存地址映射到物理内存地址上,单位是页
2.什么是页表?
在现代操作系统中,不管是虚拟内存地址还是物理内存地址,都是以页尾单位管理的,而不是大家以为的字节。(一个内存页是一段固定的地址,典型的内存页的大小是4K)。所以内存地址可以分为页号和页内偏移量
。
三,Linux进程级的内存管理
首先,我们可以了解一下一个进程的内核空间:
可以看到一个进程地址空间的主要成分为:
-
正文:这是整个用户空间的最低地址部分,存放的是指令(也就是程序所编译成的可执行机器码)
-
初始化数据段:这里存放的是初始化过的全局变量
-