程序员自己手动申请和释放堆区空间,更灵活。(以下函数使用时都必须包含头文件<stdlib.h>)
malloc函数
向内存堆区申请一块连续可用的内存空间,并返回这块内存空间的首地址,函数定义:void* malloc(size_t num);num的单位是:字节。
返回值:
- 开辟成功,返回这块空间的首地址;
- 开辟失败,返回NULL;(因此在每次调用完malloc函数后,要对返回只进行判断后才能使用这块空间)
- 返回值是void*类型,具体使用时要进行强制类型转换
- size = 0时,函数未定义,行为取决于编译器本身。
int main()
{
int* p = (int*)malloc(5 * sizeof(int));
if (p == NULL)
{
perror("malloc");
return 1;
}
int i = 0;
for (i = 0;i < 5;i++)
{
*(p + i) = i + 1;
}
free(p);
p = NULL;
return 0;
}
free函数
释放通过动态内存分配函数申请的内存空间,函数定义:void free(void* ptr);
- ptr指向释放内存块指针;
- ptr指向的内存空间不是动态开辟的,则函数为定义,不会有操作;
- ptr为NULL,则什么都不做;
- 在写代码时,一般释放完内存空间,要将该指针指向NULL.
calloc函数
在申请完连续空间后,将每一个字节置0,再返回这块空间的首地址;
函数声明:void* calloc(size_t num,size_t size);
- num为申请个数;
- size为申请的内存空间中每个的尺寸大小;(与前面的个数对应)
- 其余用法以及返回值等均与malloc函数相同。
int main()
{
int* p = (int*)calloc(5 , sizeof(int));//创建5个整形变量的连续空间,并将其全部置0
if (p == NULL)//判断空间是否申请成功
{
perror("calloc");
return 1;
}
int i = 0;
for (i = 0;i < 5;i++)
{
*(p + i) = i + 1;
}
free(p);//释放空间
p = NULL;//释放后,p为野指针,让其指向NULL
return 0;
}
realloc函数
对已经开辟的动态内存空间的大小进行调整(扩大或者缩小)。
函数声明:void* realloc(void* ptr,size_t size);
- ptr指向要调整的内存空间的起始地址,如果ptr指向NULL,则realloc函数和malloc函数的功能基本一致;
- size是调整完之后内存空间的大小,单位是:字节;
- 返回值:调整成功,返回调整后的内存空间的首地址(可能与原地址不同);调整失败,返回NULL,原内存空间保持不变。
realloc调整内存空间大小的两种情况
- 在堆区寻找新的满足要求的内存空间;
- 将原内存空间的数据拷贝到新内存空间中;
- 释放就内存空间,返回新内存空间的起始地址。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)calloc(5 , sizeof(int));
if (p == NULL)
{
perror("calloc");
return 1;
}
int i = 0;
for (i = 0;i < 5;i++)
{
*(p + i) = i + 1;
}
int* ptr = (int*)realloc(p, 10 * sizeof(int));
//对动态内存空间进行扩展,20个字节扩展到40个字节
if (ptr == NULL)
{
perror("realloc");
return 2;
}
p = ptr;
ptr = NULL;
for (i = 5; i < 10; i++)
{
p[i] = i + 1;
}
free(p);
p = NULL;
return 0;
}
柔性数组
结构体+动态内存管理
结构体中最后一个成员,且未指定数组长度。
柔性数组的特点
柔性数组的优点
#include<stdio.h>
#include<stdlib.h>
struct Std
{
int a;
int arr[];
};
int main()
{
struct Std* p = (struct Std*)malloc(sizeof(struct Std) + 5 * sizeof(int));
if (p == NULL)
{
perror("malloc");
return 1;
}
p->a = 77;
int i = 0;
for (i = 0;i < 5;i++)
{
p->arr[i] = i + 1;
}
struct Std* ptr = (struct Std*)realloc(p,sizeof(struct Std) + 10 * sizeof(int));
//对柔性数组的长度进行扩容
if (ptr == NULL)
{
perror("realloc");
return 2;
}
p = ptr;
ptr = NULL;
for (i = 5;i < 10;i++)
{
p->arr[i] = i + 1;
}
for (i = 0;i < 10;i++)
{
printf("%d ",p->arr [i]);
}
free(p);
p = NULL;
return 0;
}





