Linux环境应用编程(二):内存分配

一:概述

        许多系统程序需要为动态数据结构(链表和二叉树)分配额外内存,此类数据结构的大小由运行时获取的信息决定。

        进程可以通过增加堆的大小来分配内存,所谓堆是一段长度可变的连续虚拟内存,始于进程的未初始化数据段末尾,随着内存的分配和释放而增减,通常将堆的当前内存边界称为“program break”。

二:在堆上分配内存

1、调整program break

#include <unistd.h>

int brk(void *addr);

void *sbrk(intptr_t increment);

       改变堆的大小其实就像命令内核改变进程的program break位置一样。program break位置抬高后,程序可以访问新分配区域内的任何内存地址,而此时物理内存页尚未分配。内核会在进程首次试图访问这些虚拟内存地址时自动分配新的物理内存页。

brk:系统调用会将program break设置为参数addr所指定的位置,由于虚拟内存是以页为单位进行分配,addr实际会四舍五入到下一个内存页的边界。如果addr值低于初始值&end时会导致无法预知的行为。

sbrk:在program break原有地址上增加参数increment传入的大小,调用成功返回新分配内存的起始地址的指针。

2、malloc()和free()

#include <stdlib.h>

void *malloc(size_t size);
void free(void *ptr);

malloc:在堆上分配参数size子节大小的内存,返回指向新分配内存的起始地址的指针。分配的内存并未初始化。

free:ptr参数指向内存块,一般为malloc调用返回值。

3、calloc()和realloc()

扫描二维码关注公众号,回复: 12178702 查看本文章
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);

calloc:nmemb指定分配对象的数量,size指定每个对象的大小。返回值为指向该内存的指针,如果分配失败则返回NULL,calloc分配的内存已经被初始化为0。

realloc:在已有内存的基础上调整内存的大小。

上面两个内存请求调用均由free()来释放。

4、分配对齐的内存:memalign()和posix_memalign()

#include <stdlib.h>
int posix_memalign(void **memptr, size_t alignment, size_t size);


#include <malloc.h>
void *memalign(size_t alignment, size_t size);

三:在堆栈上分配内存

#include <alloca.h>

void *alloca(size_t size);

alloca()调用也是可以动态分配内存,不过不是从堆上分配内存,而是通过增加栈帧的大小从堆栈上分配。不能使用free来释放,会随着栈帧的移除自动释放。

猜你喜欢

转载自blog.csdn.net/qq_34968572/article/details/109508117