目录
前言
为什么需要动态内存呢?,一般开辟空间都是固定的,这样局限性太大了,当我们需要更大的空间时就需要进行多处修改,几行代码修改的话还行,但是几万行代码进行修改那工程量就太大了;需要的空间不需要那么多,就会出现空间浪费,这时候就需要动态内存,需要多大的空间就开辟多大的空间。
一、malloc函数<stdilb.h>
开辟动态空间就少不了开辟内存空间的函数,想这样的函数还有两个,分别是calloc函数和realloc函数。
先来介绍malloc函数:
void* malloc(size_t size);
malloc函数向内存申请连续的空间,传参只需要传要开辟内存空间的大小,单位是字节,返回值是void*,接收时需要强制转换为所需要类型;
当开辟内存空间成功之后,就会返回指向该内存块的指针;
开辟内存空间失败,就返回NULL指针。
使用完该申请的内存空间后,就需要释放该空间,这时候就要用到一个函数:free函数,一般情况申请动态内存函数和free函数一起出现的,向操作系统申请一处空间使用完后,使用free函数来释放申请的空间,还给操作系统,要注意的是,释放完空间还需要将指向该空间的指针置为NULL,不然会成为野指针。
示例:
#include<stdlib.h>
int main()
{
char* p = (char*)malloc(6 * sizeof(char)); // 分配6个字节的空间
if (p == NULL) {
// 处理内存分配失败的情况
return 1;
}
strcpy(p, "abcde"); // 正确复制字符串到分配的内存
printf("%s", p);
free(p); // 正确释放之前分配的内存
p = NULL;
return 0;
}
运行结果:
申请内存空间要对其进行判断是否为NULL,内存开辟失败就返回1;接着就是释放p指针指向的空间(申请的内存空间)。
二、calloc函数<stdilb.h>
void* calloc (size_t num, size_t size);
从上面可以看出calloc函数需要两个参数,num是申请多少内存,size为申请内存的类型大小。size_t为无符号型。
功能和malloc函数大差不大,值得注意的是,calloc函数在申请内存后会自动进行初始化,所有值为0。
调试可以看到p指向的那处内存空间都初始化为0。
接收时需要强制转换需要的类型,申请内存空间使用完后记得要释放空间。
三、realloc函数<stdlib.h>
void* realloc (void* ptr, size_t size);
有时会我们发现过去申请的空间太⼩了,有时候我们⼜会觉得申请的空间过⼤了,那为了合理的使 ⽤内存,我们⼀定会对内存的⼤⼩做灵活的调整。那 realloc 函数就可以做到对动态开辟内存⼤ ⼩的调整。
realloc函数的出现让调整内存空间更加灵活
ptr是要调整内存大小的指针,size是调整后新的内存大小,单位是字节。
返回值为开辟内存的起始地址。
该函数调整原来空间大小时,会把原来空间的数据移动到新开辟的内存空间上。
realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有⾜够⼤的空间
情况2:原有空间之后没有⾜够⼤的空间
情况1: 当是情况1的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发⽣变化。
情况2: 当是情况2的时候,原有空间之后没有⾜够多的空间时,扩展的⽅法是:在堆空间上另找⼀个合适⼤⼩ 的连续空间来使⽤。这样函数返回的是⼀个新的内存地址。
示例:
#include<stdlib.h>
int main()
{
char* p=(char*)malloc(1);
if (p == NULL)
{
return 1;
}
char* ptr = (char*)realloc(p, 5 * sizeof(char));
if (ptr == NULL)
{
return 1;
}
ptr = "abcd";
printf("%s", ptr);
free(ptr);
ptr=NULL;
free(p);
p=NULL;
return 0;
}
运行结果:
动态内存管理就分享到这里咯,有问题的欢迎在评论区讨论~