Loading... ## API相关 | 函数 | 说明 | | | - | - | - | | int brk(void *addr) | 分配堆空间系统API | | | void *sbrk(int ptr_t increment) | 获取系统维护的堆指针 | | | void *malloc(size_t size) | C语言分配堆内存 | | | void free(void *ptr) | C语言堆释放堆内存 | | | void *mmap(void *addr ,size_t lenth,int flags,int fd,off_t offset) | 分配虚拟内存空间,Linux系统API | | | int munmap(void *addr,size_t lenth) | 释放虚拟内存,Linux系统 | | | int mprotect(const void *start,size_t len,int prot) | 修改指定内存属性 | | ## 代码 ``` #include <unistd.h> #include <stdio.h> #include <string.h> int main() { // 在虚拟地址空间中,申请一个堆的起始地址, void* heap = sbrk(0); // 在堆指针的基础上申请空间 brk(heap + 10); // 向申请的堆空间中写入内容 strcpy(heap, "hello"); // 输出堆空间中的内容 printf("heap: %s\n", heap); // 如果要释放堆空间,就将指针指回首地址 brk(heap); return 0; } #include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> /* 功能: 向系统申请一段虚拟空间 参数1 addr: 映射区的开始地址,0系统分配 参数2 length:申请的长度,按页对齐(4k) 参数3 prot: 期望的内存保护标志 参数4 flags: 指定映射对象的类型,映射选项和映射页是否可以共享 参数5 fd: 有效的文件描述符 参数6 offset:被映射对象内容的起点 返回值: 成功返回被映射区的指针,失败返回-1 void * mmap(void *addr, size_t lenght, int prot, int flags, int fd, off_t offset); */ int main() { void* buffer = mmap( 0, // 申请的空间从哪里开始,0 表示系统分配 0x1000, // 申请的大小,必须是分页的整数倍 sysconf(_SC_PAGESIZE) PROT_WRITE | PROT_READ, // 内存的保护属性 MAP_ANONYMOUS | MAP_PRIVATE, // 表示申请一块匿名的私有空间 0, 0); // 文件描述符,表示要映射哪个文件,和从哪里开始映射 memcpy(buffer, "hello world", 12); printf("%s\n", buffer); munmap(buffer, 0x1000); return 0; } #include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> void* aligment(void* address) { return (void*)((long long)address & ~0xfff); } int main() { // 一个局部变量指向了常量字符串 char *name = "shuaige"; // 使用 mprotect 将内存改为可写的 int result = mprotect( aligment(name), // 必须是分页粒度对齐的 0x1000, // 同上 PROT_WRITE | PROT_READ | PROT_EXEC); // 离得太近,影响了代码 // 直接修改 name 指向的内容会崩溃 name[0] = 'a'; printf("%s\n", name); return 0; } ``` ## C库函数用法 ``` #include <stdio.h> #include <malloc.h> #include <string.h> int main() { // 申请 10 个字节的空间 char* buffer = malloc(10 * sizeof(char)); // 向空间中拷贝内容(标准库中的安全函数) strncpy(buffer, "hello", 6); // 输出其中的内容 printf("buffer: %s\n", buffer); // 使用 realloc 重新分配空间,并拷贝原有数据 char* buffer2 = realloc(buffer, 20); // 如果两个地址不相同,就说明新分配了,释放以前的 if (buffer2 != buffer) free(buffer); // 使用 strncat 进行安全的拼接 strncat(buffer2, " world", 7); // 输出其中的内容 printf("buffer2: %s\n", buffer); // 释放内容 free(buffer2); return 0; } ``` 最后修改:2021 年 03 月 03 日 © 转载自他站 赞 0 如果觉得我的文章对你有用,请随意赞赏