动态内存函数:malloc free calloc realloc //<stdlib.h>
- malloc
-
void* malloc(size_t size)
- 开辟成功返回开辟好空间的地址,失败返回 NULL
-
- free
- 释放动态开辟空间,该空间必须是动态开辟的
-
//当空间不在使用,则释放空间, //p虽然被释放,但地址没变,还是可以找到该空间 free(p); //断开P和该地址的联系 p = NULL;
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> int main() { //像内存申请10个int 空间 int* p = (int*)malloc(10 * sizeof(int)); if (p == NULL) { //打印失败原因 printf("%s\n", strerror(errno)); } else { //开辟成功 int i = 0; for (i = 0; i < 10; i++) { *(p + i) = i; printf("%d ", *(p + i)); } } //当空间不在使用,则释放空间, //p虽然被释放,但地址没变,还是可以找到该空间 free(p); //断开P和该地址的联系 p = NULL; return 0; }
- calloc
-
void* calloc ( size_t num, size_t size)
函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为 0,跟 malloc 区别就是是否初始化
-
int* p = (int*)calloc(10,10 * sizeof(int)); if (p == NULL) { //打印失败原因 printf("%s\n", strerror(errno)); } else { int i = 0; for (i = 0; i < 10; i++) { printf("%d ", *(p + i)); } } free(p); p = NULL;
-
- realloc
- 调整动态开辟空间的大小
-
void *realloc(void *ptr, size_t size) //ptr -- 指针指向一个要重新分配内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针。 size -- 内存块的新的大小,以字节为单位。如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针
realloc使用的注意事项:
- 如果 P 指向的空间之后有足够的空间可以追加,则直接追加,返回 P
- 如果没有足够的空间可以追加,则 realloc 会重新找一块满足需求的内存空间开辟,并且把原来内存中的数据拷贝过来,释放旧的内存空间,最后返回 新的地址
int* p = (int*)malloc(20);
if (p == NULL)
{
printf("%s\n", strerror(errno));
}
else
{
int i = 0;
for (i = 0; i < 5; i++)
{
*(p + i) = i;
}
}
int* ptr = (int*)realloc(p, 40);
int i = 0;
if (ptr != NULL)
{
p = ptr;
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
}
else
{
;
}
free(p);
p = NULL;
动态内存分配常见错误:
- 对空指针的解引用
- 解决方法:动态内存分配后,一定要对返回值进行判断 (?==NULL)
- 对动态开辟内存的越界访问
- 对非动态开辟的空间 free
- 使用 free 释放动态开辟内存的一部分
- 对同一块动态内存的多次释放
- 解决方法 free(p) 后,将 p 置为 NULL
- 对动态开辟的空间忘记释放(会造成内存泄漏)
柔性数组:结构体中的最后一个元素允许是未知大小的数组,这就叫 柔性数组 成员
Struct S
{
int n;
char c;
int arr[0];//柔性数组成员,也可以写成 arr[]
}
struct s* p = (struct s*)malloc(sizeof(struct S) + 10 * sizeof(int));
free(p);
p=NULL;
柔性数组前,至少有一个其他成员
sizeof 返回的这种结构大小不包括柔性数组的内存
包含柔性数组成员的结构用 malloc 进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小