1.malloc:基础堆内存分配
  • 函数原型:
void malloc(size_t size);
  • 功能:从堆中分配一块大小为size字节的连续内存块,内存内容保留随机垃圾数据(未初始化)。
  • 参数:
    • size为需要分配的内存字节数(size_t是无符号64位整数类型)。
  • 返回值:成功返回指向内存块的void指针(可强制转换为任意数据类型指针),失败返回NULL(内存不足时)。
  • 注意:malloc(0)行为未定义,部分系统返回NULL,部分返回非NULL但不可使用的小内存块,避免使用。
2.calloc:初始化堆内存分配
  • 函数原型:
void calloc(size_t nmemb,size_t size);
  • 功能:从堆中分配nmemb个大小为size字节的连续内存块(总大小=nmembsize),且将内存所有字节初始化为0
  • 优势:相比malloc,无需手动调用memset清零,适合创建数组、结构体等需要初始化为空的内存。
  • 返回值:成功返回内存块指针,失败返回NULL。
3.realloc:堆内存大小调整
  • 函数原型:
void *realloc(void *ptr,size_t size);
  • 功能:修改已分配内存块(malloc/calloc分配)的大小,支持扩容或缩容。
  • 核心规则:
    • ptr为NULL时,等价于malloc(size),直接分配新内存。
    • size为0时,等价于free(ptr),释放内存并返回NULL。
    • 扩容时:若原内存块后续有足够连续空间,直接扩展并返回原指针;若空间不足,重新分配新内存块、拷贝原数据、释放原内存,返回新指针。
  • 返回值:成功返回新内存块指针,失败返回NULL(原内存块保留,不会丢失数据)。
4.free:堆内存释放
  • 函数原型:
void free(void *ptr);
  • 功能:释放由malloc/calloc/realloc分配的内存块,将内存归还堆区,供后续分配复用。
  • 注意:
    • ptr必须是malloc/calloc/realloc返回的有效指针,不可释放栈内存、未分配内存。
    • 释放NULL指针是安全的,无任何副作用(推荐释放前先判空)。
    • 内存释放后,ptr不会自动置为NULL,会变成「野指针」,建议手动置NULL避免悬空访问。
    • 不可重复释放同一内存块,会导致内存损坏、程序崩溃。
5.memset:内存块初始化
  • 函数原型:
void *memset(void *s,int c,size_t n);
  • 功能:将内存块s的前n个字节全部设置为字符c(int类型实际传入ASCIl码,可直接传字符常量)。
  • 常用场景:堆内存清零、缓冲区初始化、填充固定字符。
  • 注意:c是单字节值,若初始化非字符类型数组(如int),仅能填充低字节(常用场景:填充0或0xff)。
6.memcpy:无重叠内存拷贝
  • 函数原型:
void *memcpy(void *dest,const void *src,size_t n);
  • 功能:从源内存块src拷贝n个字节到目标内存块dest。
  • 关键限制
    • 源内存块src和目标内存块dest不能重叠(重叠拷贝会导致数据错乱、覆盖)。适用场景
    • 无重叠内存的二进制数据拷贝(结构体、数组、文件缓冲区等),效率较高。
7.memmove:重叠内存拷贝
  • 函数原型:
void *memmove(void *dest,const void *src,size_t n);
  • 功能:与memcpy功能一致,拷贝n个字节从src到dest,支持源内存与目标内存重叠。
  • 优势:内部做了内存重叠判断,先将数据拷贝到临时缓冲区,再写入目标内存,避免数据错乱,兼容性更强。
  • 适用场景:不确定内存是否重叠的拷贝场景(如数组内部数据移动),效率略低于memcpy,但更安全。
8.memcmp:内存块比较
  • 函数原型:
int memcmp(const void *s1,const void *s2,size_t n);
  • 功能:按字节逐字比较内存块s1和s2的前n个字节(按字节ASCII码值比较)。
  • 返回值:
    • 返回0:前n个字节完全相等。
    • 返回<0:s1小于s2(第一个不同字节的ASCI码更小)。
    • 返回>0:s1大于s2(第一个不同字节的ASCI码更大)。
  • 适用场景:二进制数据比较(如结构体、加密数据、缓冲区),不依赖字符串格式。
9.alloca:栈内存分配(辅助)
  • 函数原型:
void *alloca(size_t size);
  • 功能:从当前函数的栈区分配size字节的内存,无需手动释放。
  • 优势:分配速度比malloc快(栈操作无需内存碎片管理),函数返回时栈内存自动回收,无内存泄漏风险。
  • 注意:
    • 栈空间大小有限(通常几MB),不可分配过大内存,否则会导致栈溢出(程序崩溃)。
    • 分配的内存不能带出函数(函数返回后内存失效),不可用于函数返回值。
    • 非ANSIC标准,但Linux/Unix系统广泛支持,Windows下也有兼容实现。
10.内存映射:mmap/munmap(核心)
10.1.mmap:内存映射创建
  • 函数原型:
void *mmap(void addr,size t length,int prot,int flags,int fd,off_t offset);
  • 功能:mmap(memory map)将文件或设备内存映射到进程的地址空间,实现「文件 - 内存」直接映射,无需 read/write系统调用,高效支持大文件操作、进程间共享内存。
  • 参数说明:
    • addr:指定映射的起始地址(通常传NULL,由内核自动分配最优地址)。
    • length:映射内存的大小(字节数,需是页面大小的整数倍,页面大小可通过sysconf(LsC PAGEsIzE)获取)。
    • prot:映射内存的保护权限(PROT READ只读、PROT WRITE可写、PROT EXEC可执行、PROT NONE无权限)。
    • flags:映射标志(核心:MAP_SHARED共享映射,修改会同步到文件/其他进程;MAP_PRIVATE私有映射,修改仅对当前进程有效)。
    • fd:待映射文件的文件描述符(需先open打开文件,映射完成后可关闭文件描述符,映射仍有效)。
    • offset:文件偏移量(需是页面大小的整数倍,从文件开头偏移该大小开始映射)。返回值成功返回映射内存的起始地址,失败返回MAP_FAILED(即(void)-1)并设置errno。
10.2.munmap:内存映射释放
  • 函数原型:
int munmap(void *addr,size_t length);
  • 功能:释放mmap创建的映射内存,addr为映射起始地址,length为映射大小。
  • 返回值:0表示成功,-1表示失败并设置errno。
11.内核态内存操作:kmalloc/kfree(仅内核开发)
11.1.kmalloc:内核内存分配
  • 函数原型:
void *kmalloc(size_t size,gfp_t flags);
  • 功能:从内核堆中分配连续的物理内存,内存内容未初始化。
  • 参数:
    • 关键参数flags:分配标志(核心场景)
      • GFP_KERNEL:普通内核分配,可睡眠(等待内存页框),适用于进程上下文。
      • GFP_ATOMIC:原子分配,不可睡眠,适用于中断上下文、自旋锁保护区域。
  • 返回值:成功返回内核内存指针,失败返回NULL。
11.2.kfree:内核内存释放
  • 函数原型:
void kfree(const void *ptr);
  • 功能:释放kmalloc、kzalloc(分配并清零)分配的内核内存,不可释放用户态内存。
  • 注意:内核态内存大小有限,不可随意分配大内存,且无标准C库支持,需使用内核自带工具函数。
Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐