内存区域可以分为栈、堆、静态存储区和常量存储区,局部变量,函数形参,临时变量都是在栈上获得内存的,它们获取的方式都是由编译器自动执行的。
利用指针,我们可以像汇编语言一样处理内存地址,C 标准函数库提供了许多函数来实现对堆上内存管理,其中包括:malloc函数,free函数,calloc函数和realloc函数。使用这些函数需要包含头文件stdlib.h。
四个函数之间的有区别,也有联系,我们应该学会把握这种关系,从而编出精炼而高效的程序。
在说明它们具体含义之前,先简单从字面上加以认识,前3个函数有个共同的特点,就是都带有字符”alloc”,就是”allocate”,”分配”的意思,也就是给对象分配足够的内存,” calloc()”是”分配内存给多个对象”,” malloc()”是”分配内存给一个对象”,”realloc()”是”重新分配内存”之意。”free()”就比较简单了,”释放”的意思,就是把之前所分配的内存空间给释放出来。
1. malloc()
(内存分配)
- 目的: 分配指定数量字节的内存。
- 函数签名:
void* malloc(size_t size);
- 用法:
int* arr = (int*)malloc(5 * sizeof(int));
- 注意:
- 返回指向分配内存首字节的指针。
- 所分配的内存未初始化,包含垃圾值。
2. calloc()
(连续分配)
- 目的: 分配指定数量块,每块有指定大小的内存。
- 函数签名:
void* calloc(size_t num_elements, size_t element_size);
- 用法:
int* arr = (int*)calloc(5, sizeof(int));
- 注意:
- 返回指向分配内存首字节的指针。
- 所分配的内存初始化为零。
3. realloc()
(重新分配内存)
- 目的: 更改已由先前分配的指针指向的内存块的大小。
- 函数签名:
void* realloc(void* ptr, size_t size);
- 用法:
arr = (int*)realloc(arr, 10 * sizeof(int));
- 注意:
- 如果重新分配成功,将返回一个新的指针,旧指针可能无效。
- 旧内存块的内容被复制到新的块。
4. free()
(释放内存)
- 目的: 释放先前由
malloc()
、calloc()
或realloc()
分配的内存块。 - 函数签名:
void free(void* ptr);
- 用法:
free(arr);
- 注意:
- 释放由
ptr
指向的内存空间,ptr
必须是之前由malloc()
、calloc()
或realloc()
调用返回的。
- 释放由
5. alloca()
(在堆栈上分配空间)
- 目的: 在堆栈上分配指定数量字节的内存。
- 函数签名:
void* alloca(size_t size);
- 用法:
int* arr = (int*)alloca(5 * sizeof(int));
- 注意:
- 在堆栈上分配内存,在函数退出时会自动释放。
- 由于可移植性问题和堆栈溢出的风险,不推荐使用。
总结:
malloc()
和calloc()
在堆上分配内存。realloc()
更改先前分配的内存的大小。free()
释放内存。alloca()
在堆栈上分配内存(谨慎使用)。
记住,有效的内存管理对于避免内存泄漏和提高程序性能至关重要。