# 内存 - [基本概念](#section1392116583424) - [使用场景](#section159581619194319) - [接口说明](#section114001032104317) ## 基本概念 内存管理是开发过程中必须要关注的重要过程,它包括内存的分配、使用和回收。 良好的内存管理对于提高软件性能和可靠性有着十分重要的意义。 ## 使用场景 针对用户态开发,OpenHarmony内核提供了一套内存系统调用接口,支持内存的申请释放、重映射、内存属性的设置等,还有C库的标准内存操作函数。 ## 接口说明 **表 1** 标准C库相关接口

头文件

接口

功能

strings.h

int bcmp(const void *s1, const void *s2, size_t n)

比较字节序列。

strings.h

void bcopy(const void *src, void *dest, size_t n)

拷贝字节序列。

strings.h

void bzero(void *s, size_t n)

写入零值字节。

string.h

void *memccpy(void *dest, const void *src, int c, size_t n)

拷贝src 所指的内存内容前n 个字节到dest 所指的地址上。复制时检查参数c 是否出现,若是则返回dest 中值为c 的下一个字节地址。

string.h

void *memchr(const void *s, int c, size_t n)

在s所指内存的前n个字节中查找c。

string.h

int memcmp(const void *s1, const void *s2, size_t n)

内存比较。

string.h

void *memcpy(void *dest, const void *src, size_t n)

内存拷贝。

string.h

void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)

找到一个子串。

string.h

void *memmove(void *dest, const void *src, size_t n)

内存移动。

string.h

void *mempcpy(void *dest, const void *src, size_t n)

拷贝内存区域。

string.h

void *memset(void *s, int c, size_t n)

内存初始化。

stdlib.h

void *malloc(size_t size)

申请内存。

stdlib.h

void *calloc(size_t nmemb, size_t size)

申请内存并清零。

stdlib.h

void *realloc(void *ptr, size_t size)

重分配内存。

stdlib.h/malloc.h

void *valloc(size_t size)

分配以页对齐的内存。

stdlib.h

void free(void *ptr)

释放内存。

malloc.h

size_t malloc_usable_size(void *ptr)

获取从堆分配的内存块的大小。

unistd.h

int getpagesize(void)

获取页面大小。

unistd.h

void *sbrk(intptr_t increment)

更改数据段大小。

差异接口详细说明: - **mmap** **函数原型:** void \*mmap\(void \*addr, size\_t length, int prot, int flags, int fd, off\_t offset\); **函数功能:**申请虚拟内存。 **参数说明:**

参数

描述

addr

用来请求使用某个特定的虚拟内存地址。如果取NULL,结果地址就将自动分配(这是推荐的做法),否则会降低程序的可移植性,因为不同系统的可用地址范围不一样。

length

内存段的大小。

prot

用于设置内存段的访问权限,有如下权限:

  • PROT_READ:允许读该内存段。
  • PROT_WRITE:允许写该内存段。
  • PROT_EXEC:允许执行该内存段。
  • PROT_NONE:不能访问。

flags

控制程序对内存段的改变所造成的影响,有如下属性:

  • MAP_PRIVATE:内存段私有,对它的修改值仅对本进程有效。
  • MAP_SHARED:把对该内存段的修改保存到磁盘文件中。

fd

打开的文件描述符。

offset

用以改变经共享内存段访问的文件中数据的起始偏移值。

>![](../public_sys-resources/icon-note.gif) **说明:** >mmap与Linux实现差异详见[与Linux标准库的差异](kernel-lite-small-lib-differ.md)章节。 **返回值:** - 成功返回:虚拟内存地址,这地址是页对齐。 - 失败返回:\(void \*\)-1。 - **munmap接口** **函数原型:** int munmap\(void \*addr, size\_t length\); **函数功能:**释放虚拟内存。 **参数说明:**

参数

描述

addr

虚拟内存起始位置。

length

内存段的大小。

**返回值:** - 成功返回0。 - 失败返回-1。 - **mprotect接口** **函数原型:** int mprotect\(void \*addr, size\_t length, int prot\); **函数功能:**修改内存段的访问权限。 **参数说明:**

参数

描述

addr

内存段起始地址,必须页对齐;访问权限异常,内核将直接抛异常并且kill该进程,而不会产生SIGSEGV信号给当前进程。

length

内存段的大小。

prot

内存段的访问权限,有如下定义:

  • PROT_READ:允许读该内存段。
  • PROT_WRITE:允许写该内存段。
  • PROT_EXEC:允许执行该内存段。
  • PROT_NONE:不能访问。
**返回值:** - 成功返回0。 - 失败返回-1。 - **mremap接口** **函数原型:** void \*mremap\(void \*old\_address, size\_t old\_size, size\_t new\_size, int flags, void new\_address\); **函数功能:**重新映射虚拟内存地址。 **参数说明:**

参数

描述

old_address

需要扩大(或缩小)的内存段的原始地址。注意old_address必须是页对齐。

old_size

内存段的原始大小。

new_size

新内存段的大小。

flags

如果没有足够的空间在当前位置展开映射,则返回失败

  • MREMAP_MAYMOVE:允许内核将映射重定位到新的虚拟地址。
  • MREMAP_FIXED:mremap()接受第五个参数,void *new_address,该参数指定映射地址必须页对齐;在new_address和new_size指定的地址范围内的所有先前映射都被解除映射。如果指定了MREMAP_FIXED,还必须指定MREMAP_MAYMOVE。
**返回值:** - 成功返回:重新映射后的虚拟内存地址。 - 失败返回:\(\(void \*\)-1\)。