一,我们先来介绍一下今天的第一个函数malloc:
参数:无符号整形。
返回值:void*的指针,内存开创成功后返回的是内存的起始地址,如果失败,返回NULL;
功能就是开辟指定大小的内存空间,但是不对该内存进行初始化,保留的是不确定的值。
我们在使用该函数的时候要注意对malloc之后的返回值进行强制类型转换,以便达到我们的使用目的。
接下来我们以一个例子来使用一下malloc
#include <string.h>
#include <stdio.h>
#include <errno.h>
int main()
{
//使用malloc开辟一块内存,并给该内存赋值。
int* ptr = (int*)malloc(20);//开辟20个字节的空间
int* p = ptr;
//判断一下返回值是否正常
if (p == NULL)
{
//显示一下错误信息,并介绍代码的运行
strerror(errno);
free(ptr);
p = NULL;
ptr = NULL;
return 1;
}
for (int i = 0; i < 5; i++)
{
*p = i;
p++;
}
for (int i = 0; i < 5; i++)
{
printf("%d ", *(ptr + i));
}
//释放
free(ptr);
ptr = NULL;
p = NULL;
return 0;
}
无论在使用那个动态内存函数开辟的空间,大家在最后使用之后一定要注意用free()释放,释放时使用的时内存的首地址,所以我上面使用了p来进行赋值操作,但是这有点繁琐了,使用一个指针也是能完成上面的要求的,下面说代码的优化:
#include <string.h>
#include <stdio.h>
#include <errno.h>
int main()
{
//使用malloc开辟一块内存,并给该内存赋值。
int* ptr = (int*)malloc(20);//开辟20个字节的空间
//判断一下返回值是否正常
if (ptr == NULL)
{
//显示一下错误信息,并介绍代码的运行
strerror(errno);
//这里可以不进行释放,因为我使用了return程序结束之后,内存就释放掉了!
//free(ptr);
//ptr = NULL;
return 1;
}
for (int i = 0; i < 5; i++)
{
//这样ptr的值就没有改变。
*(ptr + i) = i;
}
for (int i = 0; i < 5; i++)
{
printf("%d ", *(ptr + i));
}
//释放
free(ptr);
ptr = NULL;
return 0;
}
二,calloc函数:
同样我们还是先来看一下这个函数的返回值和参数以及功能有哪些
参数:num是开辟的字节大小,size是开辟的个数。
返回值:void*类型,开辟内存成功也是返回首地址,失败返回NULL;
与malloc不同的是,calloc会对开辟的内存进行一个初始化的操作,初始化全为0。
用例:
int main()
{
//开辟4个字节的内存5个
int* ptr = (int*)calloc(5, 4);
//int* ptr = (int*)calloc(5, sizeof(int));
if (ptr == NULL)
{
strerror(errno);
return 1;
}
for (int i = 0; i < 5; i++)
{
*(ptr + i) = i;
}
for (int i = 0; i < 5; i++)
{
printf("%d ", *(ptr + i));
}
//释放
free(ptr);
ptr = NULL;
return 0;
}
calloc相比于malloc更加灵活了一些!,区别就是calloc会对内存初始化为0,而malloc不会。
三,realloc函数:
reaclloc函数可以更改指定内存块的大小
参数:ptr指向的内存块,size无符号整形
返回值:更改成功返回有两种可能性:
1,返回值原有的地址,2,返回新的地址
为什么会有这两种情况呢?原因是,当更改的内存和原有的内存是连续的话,更改完之后内存快的地址没有发生改变,返回的就是原地址。如下图:(减小原内存快空间的话返回的肯定是原地址)
并不是所有时刻更改的内存都是连续的,那么当更改的内存并不连续的时候realloc会新开辟一块大的空间,并将原数据拷贝到新开辟的内存快中,并返回新的内存地址!并将原内存块释放掉(自动释放)如下图:
注意,新分配出来的空间也是不进行初始化的!
如果更改不成功的话,返回NULL;
下面我们对第一例代码进行改造,让得能放下10个数据。
#include <string.h>
#include <stdio.h>
#include <errno.h>
int main()
{
int* ptr = (int*)malloc(20);
if (ptr == NULL)
{
strerror(errno);
return 1;
}
ptr = (int*)realloc(ptr, 40);
for (int i = 0; i < 10; i++)
{
*(ptr + i) = i;
}
for (int i = 0; i < 10; i++)
{
printf("%d ", *(ptr + i));
}
//释放
free(ptr);
ptr = NULL;
return 0;
}
运行结果: