GNU_linux编程指南读书笔记6--内存管理

一 c内存管理回顾
malloc calloc realloc free
1 malloc函数的使用
#include<stdlib.h>
void *malloc(size_t size);

char *pmem;
if((pem=malloc(sizeof(char)*100))!=NULL)
{
    //***********************
}
不必对malloc返回的类型作强制类型转换

2 calloc函数的使用
分配并初始化内存块。
#include<stdlib.h>
void *calloc(size_t nmemb,size_t size);
calloc和malloc的不同之处在于,calloc对分配到的内存进程初始化,吧每个比特位置为0。

3 realloc函数的使用
realloc能够改变以前分配的内存块的大小。可以使用realloc调整以前由malloc或calloc调用获得的内存大小。

#include<stdlib.h>
void *realloc(void *ptr,size_t size);

realloc 不对增加的内存块作初始化
realloc 如果不能扩大内存块,就返回NULL,而且保持原来的数据不动
realloc 的第一个参数如果为NULL,则它的作用和malloc函数一样
realloc 的第二个参数如果为0,则释放原来的内存块

4 free函数的使用
#include<stdlib.h>
void free(void *ptr);
内存分配函数从一个称为堆(heap)的存储池中获得内存。
内存泄露
悬空指针

二 内存映象文件
linux允许任何进程把一个磁盘文件映射到内存中,在磁盘文件和它的内存中的映象间创建逐字节的对应关系。
使用内存映象文件的另一个优点是可以共享数据,如果多个进程需要访问同样的数据,这些数据就可以保存在一个内存映象文件中,所有的进程都能访问它。

<sys/mman.h>
mmap、munmap、msync、mprotect、mlock、munlock、mlockall和munlockall。
1 mmap函数的使用
mmap函数把一个磁盘文件映像到内存中
#include<unistd.h>
#include<sys/mman.h>
void *mmap(void *start,size_t length,int port,int flags,int fd,off_t offset);
在文件描述符fd指定的打开文件中,从文件起始处便宜offset的位置开始映像到内存中start开始的地方。length指定文件被映像的大小。
映像的内存区有保护模式
PROT_NONE 不允许访问
PROT_READ 被映射内存区可读
PROT_WRITE 被映射内存区可写
PROT_EXEC 被映射内存去可执行

映像的属性由flags指定
MAP_FIXED 如果shart无效或者正在使用则失败
MAP_PRIVATE 对映像内存区的写入操作是进程私有的
MAP_SHARED 对映像内存区的写入也被复制到文件
MAP_ANON 创建匿名映像,忽略fd
MAP_DENYWRITE 不允许正常的写文件
MAP_GROWSDOWN 映像内存区是向下增长的
MAP_LOCKED 把页面锁定在内存中

如果mmap执行成功则返回指向内存区的指针,如果执行失败则返回-1,并设置errno变量。

fooset通常为0,表明整个文件都被映像到内存中。
映像内存区必须用MAP_PRIVATE标为私有,或者用MAP_SHARED标为可共享,其他的值是可选的。
似有映像似的对映像内存区的任何修改都是进程似有的,所以它们不会反应到下面的磁盘文件,其他进程也不会得到这些修改。
共享映像似的对映像内存区的任何更新都能够立即让使用同一文件作映像的其他进程看到。
为了防止写入下层的磁盘文件,可以指定MAP_DENYWRITE
MAP_FIXED 让内核把映像定位在特定的地址

2 munmap函数的使用
调用munmap解除内存影响并把内存释放返回给操作系统
#include<unistd.h>
#include<sys/mman.h>
int munmap(void *start,size_t length);

3 msync函数的使用
把被映像的文件写入磁盘
int msync(const void 8start,size_length,int flags);
flags:
MS_ASYNC 调度一次写入操作然后返回
MS_SYNC 在msync返回前写入数据
MS_INVALIDATE 让映像到同一文件的映像无效,以便用新数据更新它们

4 mprotect函数的使用
修改在内存映像上的保护模式
#include<unistd.h>
#include<sys/mmap.h>
int mprotect(const void *start,size_t len,int prot);
mprotect把自start开始的内存区的保护模式修改为prot指定的值。

5 锁定内存
内存加锁就意味着防止一块内存区域被交换到磁盘上。

#include<unistd.h>
#include<sys/mmap.h>
int mlock(const void *start,size_t len);
int munlock(void *start,size_t len);
int mlockall(int flags);
int munlockall(void);
start指出被加锁或解锁的内存区,而len指出加锁或解锁的内存区大小。
flags:
MCL_CURRENT 在调用返回前请求锁住所有的内存页面
MCL_FUTURE 指出锁住所有增加到进程的地址空间的内存页面

6 mremap函数的使用
mremap函数用于改变一个被映像的文件的大小
void *mremap(void *old_addr,size_t old_len,size_t new_len,unsigned long flags);

你可能感兴趣的:(linux)