目录
1.malloc和free
(1)malloc函数是一个动态内存开辟函数,用此函数分配所需的内存空间,并返回一个指向它的指针。
void* malloc(size_t size)
参数:size---内存块的大小,以字节为单位。
返回值:
如果开辟成功,返回一个指针,指向已经开辟好的内存
如果开辟失败,返回一个NULL指针。
注:malloc的返回值要做检查处理
返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,需要对malloc返回的指针进行强制转换类型
#include<stdio.h>
#include<string>
#include<errno.h>
int main()
{
int arr[10] = { 0 };
int* p = (int*)malloc(40);//申请40个字节的空间
if (p == NULL) //对malloc的返回值进行检查处理
{
printf("%s\n", strerror(errno));
return 1;
}
//使用
int i = 0;
for (i = 0;i < 10;i++)//对申请的40字节空间进行赋值
{
*(p + i) = i;
}
return 0;
}
(2)free函数是用来释放之前调用 calloc、malloc 或 realloc 所分配的内存空间。
void free(void *ptr)
ptr -- 指针指向一个要释放内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。
如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
如果参数 ptr 是NULL指针,则函数什么事都不做。
free()函数之后需要将ptr指针置为空,ptr = NULL; 否则以后的ptr可能访问到已经释放过的内存,造成野指针。
free函数的具体用法:(接上面代码)
int main()
{
int arr[10] = { 0 };
int* p = (int*)malloc(40);//申请40个字节的空间
if (p == NULL) //对malloc的返回值进行检查处理
{
printf("%s\n", strerror(errno));
return 1;
}
//使用
int i = 0;
for (i = 0;i < 10;i++)
{
*(p + i) = i;
}
//进行释放内存
free(p);
p = NULL;
return 0;
}
2.calloc
calloc函数是用来分配所需的内存空间,并返回一个指向它的指针。
calloc函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
malloc 和 calloc 之间的不同点是,malloc 不会设置内存为零,而 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
void *calloc(size_t num, size_t size)
参数
- num -- 要被分配的元素个数。
- size -- 元素的大小。
返回值
calloc函数返回一个指针,指向已分配的内存。如果请求失败,则返回 NULL。
实例
下面的实例演示了 calloc() 函数的用法。
3.realloc
有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时 候内存,我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小 的调整。(可以调大,也可以调小)
realloc函数将重新调整之前调用 malloc 或 calloc 所分配的 ptr 所指向的内存块的大小。
void *realloc(void *ptr, size_t size)
参数
ptr --- 是要调整的内存地址
size --- 调整之后新大小
返回值
该函数返回一个指针 ,指向重新分配大小的内存起始位置。如果请求失败,则返回 NULL。
注意:
realloc()函数在调整内存空间时会出现两种情况(内存分布上的情况):
1.原有空间后有足够大的空间,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
2.原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小 的连续空间来使用。这样函数返回的是一个新的内存地址。
由于上述的两种情况,realloc函数的使用就要注意。接收realloc返回的地址时,需要利用中间变量,增加一步判断条件。如下代码所示:
int*p = NULL;
p = (int*)realloc(ptr, 1000);//不可用原来的 ptr 指针直接接收返回值
if(p != NULL)//当成功开辟新空间时,再把 ptr 指向新的空间
{
ptr = p;
}
//业务处理
free(ptr);
return 0;