2013年11月05日 星期二 10时16分38秒
-----------------------------------------------------------
i=100,&i=0xbfa6787c
1 #include <stdio.h>
2
3 int main()
4 {
5 int* p = (int*)0xbfa6787c;
6 printf("*p=%d\n",*p);
7 }
该程序会引发段错误
-----------------------------------------------------------
malloc()分配的内存在堆中,除了分配内存之外,还要额外占用一些空间,存储 附加数据。附加数据用于辅助操作系统管理内存。比如free()就需要知道内存的大小。附加数据是由 底层的双向链表维护
malloc()在申请少量内存时 一次映射33个内存页,如果申请大量内存(超过31个内存页)会分配比申请的内存稍多的内存页数。
free() 不一定会接触内存的映射,最后33个内存页不会接触映射,free()的真正作用是让内存可以重复使用(内存由不可用变为可用)
经验:
虽然malloc()一次映射33个内存页,会让内存越界不会引发错误,但尽量不要越界,否则可能破坏下一个变量的附加数据
-----------------------------------------------------------
sbrk()和brk() - Unix/Linux的系统函数
sbrk()和brk()是通过底层维护的一个位置来管理内存的
void* sbrk(int increment)
参数increment为正,代表申请内存,位置向后移动increment字节,扩大数据区
为0,位置不动,返回当前的位置地址
为负数,代表释放内存,位置向前移动increment字节,缩小数据区
返回的是移动之前的位置
sbrk()/brk() 是系统函数,没有malloc()那么复杂
sbrk()对分配内存简单,释放内存繁琐:brk()正好相反
int brk(void* pos)
pos是新的位置,不论以前位置在哪里,直接回到新位置,成功返回0,失败返回-1
练习:
使用sbrk()申请内存,使用brk()释放内存,实现存储一个int,一个double和一个字符串
结论:使用sbrk()申请内存,brk()释放内存最佳
-----------------------------------------------------------
mmap() 和 munmap()
权限、选项的拼接,用 位或| 即可
void* mmap(void* addr,size_t size,int prot,int flags,int fd,int off)
参数:addr 一般为NULL,内核选择映射首地址
size 映射的大小,不足一个内存页会补齐
prot 权限,固定PROT_READ|PROT_WRITE
flags 选项,常见以下值:
MAP_PRIVATE MAP_SHARED 必选其一,对内存没有区别,对文件有区别
MAP_ANONYMOUS 匿名映射,代表映射物理内存
返回映射的首地址,失败返回MAP_FAILED
系统调用:
用户空间的程序不能直接访问内核空间,但很多功能都必须进入内核空间。Unix/Linux系统在POSIX规范中定义了一系列系统函数,用于 进入内核空间,这些系统函数 叫系统调用(System call)
系统调用是用户空间和内核空间的桥梁。但频繁调用也会影响性能
文件:
标C中,关于文件的函数有哪些?
fopen() fread() fwrite() fclose() fseek() fprintf() fscanf() ftell()...
这些函数都有Unix/Linux系统调用的支持
Linux中,几乎一切都是文件,包括:文件、目录、内存、各种IO设备。因此,对文件的操作函数可以扩展到各种设备。最基本的几个函数:
open() read() write() close() ioctl()
Unix/Linux中,用文件描述符代表一个打开的文件,文件描述符 本质就是一个非负整数。但 文件的信息不存在文件描述符中。每个进程都有一个文件描述符总对应表,每个文件描述符对应一张文件表,数据都存在文件表中。
进程中同时打开的文件描述符总数有限制,为0到OPEN_MAN,Linux能同时打开256个。文件描述符可以重复利用(关闭后即可)。文件描述符0 1 2被系统预先占用,代表标准输入,标准输出和标准错误。用户的文件描述符从 3 开始。
推荐书籍: Unix环境高级编程 第二版
-----------------------------------------------------------
i=100,&i=0xbfa6787c
1 #include <stdio.h>
2
3 int main()
4 {
5 int* p = (int*)0xbfa6787c;
6 printf("*p=%d\n",*p);
7 }
该程序会引发段错误
-----------------------------------------------------------
malloc()分配的内存在堆中,除了分配内存之外,还要额外占用一些空间,存储 附加数据。附加数据用于辅助操作系统管理内存。比如free()就需要知道内存的大小。附加数据是由 底层的双向链表维护
malloc()在申请少量内存时 一次映射33个内存页,如果申请大量内存(超过31个内存页)会分配比申请的内存稍多的内存页数。
free() 不一定会接触内存的映射,最后33个内存页不会接触映射,free()的真正作用是让内存可以重复使用(内存由不可用变为可用)
经验:
虽然malloc()一次映射33个内存页,会让内存越界不会引发错误,但尽量不要越界,否则可能破坏下一个变量的附加数据
-----------------------------------------------------------
sbrk()和brk() - Unix/Linux的系统函数
sbrk()和brk()是通过底层维护的一个位置来管理内存的
void* sbrk(int increment)
参数increment为正,代表申请内存,位置向后移动increment字节,扩大数据区
为0,位置不动,返回当前的位置地址
为负数,代表释放内存,位置向前移动increment字节,缩小数据区
返回的是移动之前的位置
sbrk()/brk() 是系统函数,没有malloc()那么复杂
sbrk()对分配内存简单,释放内存繁琐:brk()正好相反
int brk(void* pos)
pos是新的位置,不论以前位置在哪里,直接回到新位置,成功返回0,失败返回-1
练习:
使用sbrk()申请内存,使用brk()释放内存,实现存储一个int,一个double和一个字符串
结论:使用sbrk()申请内存,brk()释放内存最佳
-----------------------------------------------------------
mmap() 和 munmap()
权限、选项的拼接,用 位或| 即可
void* mmap(void* addr,size_t size,int prot,int flags,int fd,int off)
参数:addr 一般为NULL,内核选择映射首地址
size 映射的大小,不足一个内存页会补齐
prot 权限,固定PROT_READ|PROT_WRITE
flags 选项,常见以下值:
MAP_PRIVATE MAP_SHARED 必选其一,对内存没有区别,对文件有区别
MAP_ANONYMOUS 匿名映射,代表映射物理内存
返回映射的首地址,失败返回MAP_FAILED
系统调用:
用户空间的程序不能直接访问内核空间,但很多功能都必须进入内核空间。Unix/Linux系统在POSIX规范中定义了一系列系统函数,用于 进入内核空间,这些系统函数 叫系统调用(System call)
系统调用是用户空间和内核空间的桥梁。但频繁调用也会影响性能
文件:
标C中,关于文件的函数有哪些?
fopen() fread() fwrite() fclose() fseek() fprintf() fscanf() ftell()...
这些函数都有Unix/Linux系统调用的支持
Linux中,几乎一切都是文件,包括:文件、目录、内存、各种IO设备。因此,对文件的操作函数可以扩展到各种设备。最基本的几个函数:
open() read() write() close() ioctl()
Unix/Linux中,用文件描述符代表一个打开的文件,文件描述符 本质就是一个非负整数。但 文件的信息不存在文件描述符中。每个进程都有一个文件描述符总对应表,每个文件描述符对应一张文件表,数据都存在文件表中。
进程中同时打开的文件描述符总数有限制,为0到OPEN_MAN,Linux能同时打开256个。文件描述符可以重复利用(关闭后即可)。文件描述符0 1 2被系统预先占用,代表标准输入,标准输出和标准错误。用户的文件描述符从 3 开始。
推荐书籍: Unix环境高级编程 第二版