Linux C函数之内存配置函数 (2009-06-29 21:20)

1. 配置和释放内存
alloca: 配置内存空间
头文件: stdlib.h
函数定义: void *alloc(size_t size);
说明: alloca()用来配置size个字节的内存空间, 然而和malloc/calloc不同的是, alloca()是从堆栈空间(stack)中配置内存, 因此在函数返回时会自动释放此空间. 若成功返回指向配置内存首地址的指针, 失败返回NULL.

calloc: 配置内存空间
头文件: stdlib.h
函数定义: void *calloc(size_t nmemb, size_t size);
说明: calloc()用来配置nmemb个相邻的内存单位, 每一单位的大小为size, 并返回指向第一个元素的指针. 这和使用下列的方式效果相同:malloc(nmemb * size); 不过, 在利用calloc()配置内存时会将内存内容初始化为0. 若配置成功则返回一指针, 失败则返回NULL.

malloc: 配置内存空间
头文件: stdlib.h
函数定义: void *malloc(size_t size);
说明: malloc()用来配置内存空间, 其大小由指定的size决定. 若成功返回一指针, 失败返回NULL.

realloc: 更改已配置的内存空间
头文件: stdlib.h
函数定义: void *realloc(void *ptr, size_t size);
说明: 参数ptr为指向先前由malloc(), calloc(), realloc()所返回的内存指针, 而参数size为新配置的内存大小, 其值可比原内存大或小. 若参数size值比原来小, 内存内容不会改变, 且返回的指针为原来内存的起始地址; 若比原来的大, 则realloc()不一定会返回原先的指针, 原来的内容虽然不会改变, 但新多出的内存则未设初值. 若是参数ptr为NULL, 此调用相当于malloc(size), 若参数size为0, 此调用相当于free(ptr). 若配置成功返回一指针, 失败返回NULL.

free: 释放原先配置的你存
头文件: stdlib.h
函数定义: void free(void *ptr);
说明: 参数ptr为指向先前由malloc(), calloc()或realloc()所返回的内存指针. 调用free()后ptr所指的内存空间便会被收回. 假若参数ptr所指的内存空间已被收回或是未知的内存地址, 则调用free()可能会有无法预期的情况发生. 若参数ptr为NULL, 则free()不会有任何作用.

2. 建立和解除内存映射
mmap: 建立内存映射
头文件: unistd.h, sys/mman.h
函数定义: void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
说明: mmap()用来将某个文件内容映射到内存中, 对该内存区域的存取即是直接对该文件内容的读写.
    参数start指向欲对应的内存起始地址, 通常设为NULL, 代表让系统自动选定地址, 对应成功后该地址会返回. 参数length代表将文件中多大的部分对应到内存. 参数prot代表映射区域的保护方式, 有下列组合:
   PROT_EXEC 映射区域可被执行.
   PROT_READ 映射区域可被读取.
   PROT_WRITE 映射区域可被写入.
   PROT_NONE 映射区域不能存取.
参数flags会影响映射区域的各种特性:
   MAP_FIXED 如果参数start所指的地址无法成功建立映射时, 则放弃映射, 不对地址做修正. 通常不鼓励用此旗标.
   MAP_SHARED 对映射区域的写入数据会复制回文件内, 而且允许其他映射该文件的进程共享.
   MAP_PRIVATE 对映射区域的写入操作会产生一个映射文件的复制, 即私人的"写入时复制"(copy on write). 对此区域作的任何修改都不会写回原来的文件内容.
   MAP_ANONYMOUS 建立匿名映射. 此时会忽略参数fd, 不涉及文件, 而且映射区域无法和其他进程共享.
   MAP_DENYWRITE 只允许对映射区域的写入操作, 其他对文件直接写入的操作将会被拒绝.
   MAP_LOCKED 将映射区域锁定住, 这表示该区域不会被置换(swap).
在调用mmap()时必须要指定MAP_SHARED或MAP_PRIVATE. 参数fd为open()返回的文件描述词, 代表欲映射到内存的文件. 参数offset为文件映射的偏移量, 通常设置为0, 代表从文件最前方开始对应, offset必须是分页大小的整数倍.
    若映射成功则返回映射区的内存起始地址, 否则返回MAP_FAILED(-1), 错误原因存于errno中. 错误代码:
   EBADF 参数fd不是有效的文件描述词.
   EACCES 存取权限有误. 如果是MAP_PRIVATE情况下文件必须可读, 使用MAP_SHARED则要有PROT_WRITE以及该文件要能写入.
   EINVAL 参数 start、length或offset有一个不合法.
   EAGAIN 文件被锁住,或是有太多内存被锁住.
   ENOMEM 内存不足.

munmap: 解除内存映射
头文件: unistd.h, sys/mman.h
函数定义: int munmap(void *start, size_t length);
说明: munmap()用来取消参数start所指的映射内存起始地址, 参数length则是欲取消的内存大小. 当进程结束或利用exec相关函数来执行其他程序时, 映射内存会自动解除, 但关闭对应的文件描述词时不会解除映射.
    如果解除映射成功则返回0, 否则返回-1, 错误原因存于errno中. EINVAL参数start或length不合法.
应用举例: 利用mmap()来读取/etc/passwd文件内容
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
int main(void)
{
int fd;
void *start;
struct stat sb;
fd = open("/etc/passwd", O_RDONLY);
fstat(fd, &sb);
start = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if(start == MAP_FAILED)
   return -1;
printf("%s", start);
munmap(start, sb.st_size);
close(fd);
return 0;
}
运行结果: 略

3. 其它
brk: 改变数据字节的范围
头文件: stdlib.h
函数定义: int brk(void *end_data_segment);
说明: brk()用来依参数end_data_segment所指的数值设成新的数据字节范围.若函数调用成功则返回0. 函数调用失败则返回-1, 将errno设为ENOMEM.
sbrk: 增加程序可用的数据空间

头文件: stdlib.h
函数定义: void *sbrk(ptrdiff_t increment);
说明: sbrk()用来增加程序可用的数据空间, 增加大小由参数increment决定. 若函数调用成功则返回 一指针, 指向新的内存空间. 函数调用失败则返回-1, 将errno设为ENOMEM.

getsizepage: 取得内存分页大小
头文件: unistd.h
函数定义: size_t getpagesize(void);
说明: 返回内存一分页的大小, 单位为字节(byte). 此为系统的分页大小, 不一定会和硬件分页大小相同. 在Intel x86上其返回值应为4096bytes.
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值