我们为什么要动态分配内存?
int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间
我们可以看到上述空间的开辟是固定的,数组在声明时必须指定数组的大小。
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道, 那数组的编译时开辟空间的方式就不能满足了。
这时候就只能试试动态存开辟了。
动态内存函数的介绍:
malloc
void* malloc (size_t size);
如果开辟成功,则返回一个指向开辟好空间的指针。
如果开辟失败,则返回一个
NULL
指针,因此
malloc
的返回值一定要做检查。
返回值的类型是
void*
,所以
malloc
函数并不知道开辟空间的类型,具体在使用的时候使用者自己
来决定。
如果参数
size
为
0
,
malloc
的行为是标准是未定义的,取决于编译器。
malloc不会初始化数据
free
void free (void* ptr);
如果参数
ptr
指向的空间不是动态开辟的,那
free
函数的行为是未定义的。
如果参数
ptr
是
NULL
指针,则函数什么事都不做。
#include <stdio.h>
int main()
{
//代码1
int num = 0;
scanf("%d", &num);
int arr[num] = {0};
//代码2
int* ptr = NULL;
ptr = (int*)malloc(num*sizeof(int));
if(NULL != ptr)//判断ptr指针是否为空
{
int i = 0;
for(i=0; i<num; i++)
{
*(ptr+i) = 0;
}
}
free(ptr);//释放ptr所指向的动态内存
ptr = NULL;//要把ptr置为NULL
return 0; }
我们老话说有借有还,再借不难,free就是把malloc等函数动态开辟的空间还给系统。
colloc
void* calloc (size_t num, size_t size);
函数的功能是为
num
个大小为
size
的元素开辟一块空间,并且把空间的每个字节初始化为
0
。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
所以如果我们对申请的内存空间的内容要求初始化,那么可以很方便的使用
calloc
函数来完成。
realloc
void* realloc (void* ptr, size_t size);
ptr
是要调整的内存地址
size
调整之后新大小
返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新
的空间。
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
return 1;
//使用....
//增加空间
int* ptr = (int*)realloc(p, 80);//用ptr存放增加空间的地址
//如果开辟失败对原来malloc开辟的空间不会有影响
//当realloc开辟失败的是,返回的是NULL
if (ptr != NULL)
{
p = ptr;
ptr = NULL;
}
//使用....
//释放
free(p);
p = NULL;
return 0;
}
realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有足够大的空间
情况2:原有空间之后没有足够大的空间
希望大家可以看懂