作者:起薪d这帖 | 来源:互联网 | 2024-11-14 13:38
malloc是C语言中的一个标准库函数,全称为memoryallocation,即动态内存分配。它用于在程序运行时申请一块指定大小的连续内存区域,并返回该区域的起始地址。当无法预先确定内存的具体位置时,可以通过malloc动态分配内存。
malloc 的全称是 memory allocation,中文译为动态内存分配。它用于在程序运行时申请一块指定大小的连续内存区域,并返回该区域的起始地址。当无法预先确定内存的具体位置时,可以通过 malloc 动态分配内存,且分配的大小就是程序要求的大小。
函数定义
malloc 的函数原型为:void *malloc(size_t size); 其作用是在内存的动态存储区中分配一个长度为 size 的连续空间。此函数的返回值是分配区域的起始地址,即一个指针,指向该分配域的开头位置。
如果分配成功,则返回指向被分配内存的指针(该存储区中的初始值不确定),否则返回空指针 NULL。当内存不再使用时,应使用 free() 函数将内存块释放。函数返回的指针需要适当对齐,以便可以用于任何数据对象。
早期版本的 malloc 返回 char 类型的指针,但新的 ANSI C 标准规定,该函数返回 void 类型的指针。因此,在使用时可能需要进行类型转换。malloc 能向系统申请分配一个长度为 num_bytes(或 size)个字节的内存块。通常,malloc 需要与 free 函数配对使用,以确保动态分配的内存能够正确释放。
工作机制
malloc 函数的核心机制在于维护一个空闲链表,该链表将所有可用的内存块连接起来。当调用 malloc 函数时,它会沿着链表寻找一个足够大的内存块来满足用户的请求。找到合适的内存块后,将其一分为二:一块与用户请求的大小相等,另一块则是剩余的部分。然后,将分配给用户的内存块返回给用户,并将剩余的内存块(如果有的话)重新放回链表中。调用 free 函数时,它会将用户释放的内存块重新连接到空闲链表上。
随着时间的推移,空闲链表可能会被分割成许多小的内存片段。如果用户请求一个较大的内存片段,而空闲链表中没有足够的连续内存块,malloc 会尝试将相邻的小内存片段合并成较大的内存块。如果仍然无法找到合适的内存块,malloc 将返回 NULL 指针。因此,在调用 malloc 动态申请内存时,必须检查其返回值是否为 NULL。
在 Linux 系统中,glibc 库通过 brk() 和 mmap() 系统调用来实现 malloc。当释放内存时,glibc 会尝试整合相邻的内存碎片,以提高内存利用率。
与 new 的区别
从本质上讲,malloc 是 C 语言标准库中的一个函数,而 new 是 C++ 语言中的关键字。malloc 需要包含头文件 stdlib.h,而 new 不需要包含任何头文件。C++ 编译器可以直接将 new 编译为目标代码,并插入相应的构造函数。
在使用上,malloc 和 new 有以下主要区别:
- new 返回指定类型的指针,并且可以自动计算所需内存的大小。而 malloc 需要手动计算字节数,并在返回后强制转换为实际类型的指针。
- malloc 只负责分配内存,不会对内存进行初始化,因此新分配的内存中的值是随机的。而 new 除了分配内存外,还会调用对象的构造函数,对内存进行初始化。
- 通过 malloc 或 new 分配的内存,在其他操作上保持一致,但在释放内存时,malloc 使用 free 函数,而 new 使用 delete 运算符。
示例代码
以下是一个简单的示例,演示如何使用 malloc 函数分配和释放内存:
#include
#include
int main() {
char *p;
p = (char *)malloc(100);
if (p) {
printf("Memory Allocated at: %p\n", p);
} else {
printf("Not Enough Memory!\n");
}
free(p);
return 0;
}