Chinaunix首页 | 论坛 | 博客
  • 博客访问: 124399
  • 博文数量: 44
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 407
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-02 21:38
文章分类
文章存档

2015年(1)

2013年(43)

我的朋友

分类: C/C++

2013-05-11 10:55:50

#include
int brk (void *end);
void * sbrk (intptr_t increment);
堆中动态存储器的分配由数据段的底部向上生长;栈从数据段的顶部向着堆往下生长。堆和栈的分界线叫做中断或中断点。
调用brk()会设置中断点(数据段的末端)的地址为end。在成功时,返回0;失败的时候,返回-1,并设置errno为ENOMEM。
调用sbrk()将数据段末端增加increment字节,increment可正可负。sbrk()返回修改后的断点。所以,increment为0时得到的是现在短点的地址:
printf(”The current break point is %p\n”,sbrk(0));
sbrk(0)得到当前堆的首地址。

在堆中分配空间:
1、malloc 申请内存后,该内存块没有被初始化,要使用memset初始化为0后在使用。
2、calloc申请内存后,该内存块就已经被初始化为0了。
3、realloc调整一个已经得到的动态内存的大小,该内存块是调用malloc或者calloc
4、valloc和malloc一样,但是返回的是页面对其的地址。
最好使用calloc,因为calloc分配的是内核本已经清0的内存块。而且使用malloc后还要调用memset来清空函数。

在栈中分配空间:
1、alloca()
#include
void * alloca (size_t size);
调用alloca成功时会返回一个指向size大小的内存指针,这块内存在栈中。当调用他的函数返回时,这块内存将自动释放;若失败,则表明栈溢出;
此函数的一个好处是调用后不用使用free来释放该内存空间。
注意:此函数通过简单的移动栈指针来代替其他的复杂的内存分配方式,提高了效率;最常用的是栈中的字符串复制。此函数容易出现栈溢出,导致程序崩溃;建议少用吧


1、字节设置函数:memset和brzeo
brzeo函数包含在#include中,现应经被淘汰,建议不用。

2、字节比较函数:memcmp和strcmp。因为结构体中字节填充的存在,所以用这两个函数来比较结构体是不安全的。只能依次比较结构体中的每一个元素。

3、字节移动函数:
(1)、memmove函数复制src的前n字节到dst,返回dst地址:
#include
void * memmove(void *dst,const void *src,size_t n);
(2)、BSD提供了一个相同功能的函数bcopy,但是源和目的是反的:
#include
void bcopy(const void *src,void *dst,size_t n);
这两个函数都可以安全的处理内存区域重叠的问题(dst的一部分在src里面)。
(3).memcpy函数比较快速。但是是不安全的,如果遇到重叠问题,函数的结果是未被定义的。
#include
void * memcpy(void *dst,const void *src,size_t n);
(4).memccpy函数是安全的内存复制函数
#include
void * memccpy(void *dst,const void *src,int c,size_t n);
memccpy()和memcpy()类似,但当它发现字节c在src指向的前n个字节中时会停止拷贝。它返回指向dst中c后一个字节的指针,或者当没有找到c时返回null。
(5).mempcpy()函数来跨过拷贝的内存:
#define _GNU_SOURCE
#include
void *mempcpy(void *dst,const void *src,size_t n);
函数mempcpy()和memcpy()几乎一样,区别在于mempcpy返回的是指向被复制的内存的最后一个字节的下一个字节的指针。当在内存中有连续的一系列数据需要拷贝时它是很有用的。它性能没有太大的提升,返回的指针只是dst+n。


3、字节搜索
(1).memchr函数从s指向的区域开的n个字节中寻找c,c将被转换为unsigned char:
#include
void *memchr(const void *s,int c, size_t n)

(2)memrchr函数返回指向第一个匹配c的字节的指针,如果没有找到c则返回NULL。
#include
void * memrchr(const void *s, int c, size_t n);

(3)对于复杂的内存中字节数组的搜索可以使用memmem函数
#define _GNU_SOURCE
#include
void *memmem(const void *haystack,size_t haystacklen,const void *needle,size_t needlelen);
此函数在指向长为haystacklen的内存块haystack中查找,并返回第一块和长为needlelen的needle匹配的子块的指针。如果函数在haystack中不能找到needle,他会返回NULL

4.字节加密函数
#define _GNU_SOURCE
#include
void *memfrob(void *s ,size_t n);
memfrob()函数将s指向的位置开始的n个字节,每个都与42进行异或操作来对数据进行加密。函数返回s。
再次对相同的区域调用memfrob()可以将其转换回来。因此下面这行程序对于secret没有进行什么实质性的操作:
memfrob(memfrob(secret,len),len);此函数对于字符串的加密绝对的不合适


内存锁定函数:
(1).#include
int mlock(const void *addr,size_t len);
调用mlock将锁定addr开始长度为len个字节的虚拟内存。成功的话,函数返回0;失败,返回-1,并适当设置errno
成功调用会将所有包含【addr,addr+len】的物理内存页锁定
(2).#include
int mlockall(int flags);
mlockall()函数锁定一个进程在现有地址空间在物理内存中的所有页面。
flags参数有两个值可取:
MCL_CURRENT如果设置了该值,mlockall()会将所有已经被映射的页面(包括栈,数据段。映射文件)锁定进程地址空间中。
MCL_FUTURE如果设置了该值,mlockall()会将所有的未来映射的页面也锁定到进程地址空间中。大部分应用会同时设置这两个值

内核解锁
int munlock(const void *addr,size_t len);
int munlockall(void);

页面是否在物理内存中的测试函数:
int mincore(void *start, size_t length, unsigned char *vec);
阅读(3076) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~