0%

动态内存管理

malloc函数

malloc函数向内存申请一块练习的内存空间

  • 若开辟成功,返回开辟的空间的指针
  • 若开辟失败,返回NULL
  • 返回值是void*,所以malloc并不知道开辟的空间的类型,在使用开辟的空间时需要强转
  • 在开辟完空间后,要记得释放空间
  • 开辟0字节的空间在标准中是未定义的,取决于编译器。

函数声明:

1
void* malloc (size_t size);//返回值类型是void*

函数的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
int *a=(int*)malloc(sizeof(int)*10);//开辟了40字节的空间
if(a==NULL)
{
perrot("malloc");
return 1;
}
free(a);//开辟后要释放
//在free后,要把指针置NULL,因为free后,指针还记得分配的空间的地址,指针还是能找到这块空间,但是此时这块空间已经不属于当前程序了,所以,如果不置NULL,指针就会变成野指针。
a=NULL
return 0;
}

calloc函数

calloc函数与malloc函数的区别:calloc函数在申请空间的时候,会将空间中的值初始化为0

函数的声明:

1
void* calloc (size_t num, size_t size);//返回一个void*的指针

函数使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{

int* a=(int*)calloc(10,sizeof(int));//开辟10个大小为Int的空间
//此时若打印指针变量a指向的空间,会发现里面的值全是0
for(int i=0;i<10;i++)
{
printf("%d ",*(a+i));
}
free(a);
a=NULL;
return 0;
}

realloc函数

函数声明:

1
void* realloc (void* ptr, size_t size);//返回值类型是void*

当我们开辟完一快空间后,假如我们需要对这块空间的大小进行调整,那么此时就用到了realloc函数

我们可以通过realloc函数把空间缩小:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int main()
{
int *p=(int*)calloc(10,sizeof(int));
assert(p);//判断内存是否开辟成功
//缩小开辟的空间
int*ptr=(int*)realloc(p,5*sizeof(int));
//对于调整后的空间,建议用一个新的指针来接收,因为当遇到空间调整失败的情况时,如果用指针p来接收,容易丢失原数据。
//缩小空间可能存在开辟新空间的情况(不是原来空间的位置处缩小,而是再内存中另外的地址处开辟一块新的空间),所以需要用新的指针来接收
p=NULL;//因为创建了一个新的指针来接收新的地址,所以原指针要置NULL,省的后面因为它而报错
//关于p指向的空间的释放:如果是在原空间的位置处缩小的空间,那么p指向的空间就不会被释放,
//如果是开辟新的空间,那么对于p的释放就由realloc来完成,realloc会把原来p指向的空间释放掉。

free(ptr);
ptr=NULL;
return 0;
}

我们可以通过realloc函数把空间扩大:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//扩大空间也存在:1.在原空间的位置处扩大空间,2.在内存中另外的地址处开辟一块新的空间
//与缩小空间一样
int main()
{
int *p=(int*)calloc(10,sizeof(int));
assert(p);//判断内存是否开辟成功
//缩小开辟的空间
int*ptr=(int*)realloc(p,20*sizeof(int));
//对于调整后的空间,建议用一个新的指针来接收,因为当遇到空间调整失败的情况时,如果用指针p来接收,容易丢失原数据。
p=NULL;

free(ptr);
ptr=NULL;
return 0;
}

free函数

注意:当用指针接收动态开辟的空间,用free释放时,free释放的是指针指向的空间,不是指针

如果ptr指针向的空间不是动态开辟的吗,那么free函数产生的结果是未定义的

如果ptr是空指针,那么free函数什么也不做

1
void free(void*ptr);