一、malloc 和 free
malloc 函数负责向内存申请空间,free负责释放空间,它俩是一对 <stdlib.h>
molloc 申请 size 个字节大小的空间,这块空间是没有被初始化的,
返回类型,如果申请成功,将申请的地址返回,如果失败,返回NULL
free 用于释放 先前malloc、calloc、realloc 申请的空间;
如果 ptr指向的不是它仨申请的空间,会❌
如果 ptr 是空指针,啥都不会做,
释放后,不会改变ptr的值,也就是,它任然记得这块地址
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
// malloc(申请空间)和 free(释放空间)
int main()
{
int arr[10] = { 0 }; // 在栈区开辟的不可改变的空间
int* p = (int*)malloc(40);// 在堆区开辟的空间 40字节
// 打印申请失败的原因
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
int i = 0;
// 赋值
for (i = 0; i < 10; i++)
{
*(p + i) = i + 1;
}
//打印
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
//释放
free(p);
// 将p指向的内存空间还给内存,但是还记得地址
p = NULL;
return 0;
}
二、calloc 函数
用法和malloc 类似,num是元素个数,size是每个元素的大小(字节),开辟空间时,初始化为0
返回值和malloc函数一样,成功--开辟空间首地址,失败--NULL
int main()
{
// 申请10个int型大小的 空间,并且全部初始化为0
int* p=(int *)calloc(10, sizeof(int));
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p + 1));
}
//0 0 0 0 0 0 0 0 0 0
free(p);
return 0;
}
三、realloc函数
调整已申请的空间的大小
ptr 是我们要调整的,size是要调整到的大小,返回的是调整之后的地址,可能改变,也可能不变
int main()
{
int i = 0;
int* p=(int*)malloc(40);
// 赋值
for (i = 0; i < 10; i++)
{
*(p + i) = i + 1;
}
putchar('\n');
//扩容
// 防止返回的是空指针,所以用另外指针接收 realloc返回的地址
// 将p指向的空间 扩容到 80 字节
int* tp = (int*)realloc(p, 80);
if (tp != NULL)
{
p = tp;
}
//将扩容后面的赋值 0
memset(p + 10, 0, 40);
for (i = 0; i < 20; i++)
{
printf("%d ", *(p + i));
}
// 1 2 3 4 5 6 7 8 9 10 0 0 0 0 0 0 0 0 0 0
//释放
free(p);
p=NULL;
return 0;
}
当 realloc函数接收的是NULL(空指针),它的作用就相当于malloc函数
realloc(NULL,40) == malloc(40) 开辟40个字节大小的空间
四、常见的错误
1、对NULL指针的解引用操作
使用malloc 、calloc等函数时,有可能返回的是空指针(NULL),使用的时候最好先判断一下
int main()
{
int* p = (int*)malloc(40);
// 不确定p是不是 NULL,直接解引用容易出现问题
//最好先进行判断是不是空指针
/*if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}*/
*p = 10;
free(p);
p=NULL;
return 0;
}
2、对动态开辟空间的越界访问
void test()
{
int* p = (int*)calloc(5, sizeof(int));
int i = 0;
if (p == NULL)
{
printf("%s\n", strerror(errno));
}
else
{
//越界访问
for (i = 0; i <= 5; i++)
{
*(p + i) = i + 1;
}
free(p);
p = NULL;
}
}
3、对非动态开辟空间内存使用free
void test()
{
int a = 0;
int* p = &a;
free(p);
p = NULL;
}
p不是动态开辟的内存空间,不能用 free 释放,❌
4、使用free释放一块 开辟空间的一部分
void text()
{
int* p = (int*)malloc(10 * sizeof(int));
//先判断是不是空指针,再使用
// if(p=NULL)…………
for (int i = 0; i <= 5; i++)
{
*p = i;
p++;
}
//❌因为p的地址已经改变,不是开辟空间的首地址
free(p);
p = NULL;
}
尽量不要改变开辟空间的首地址,以下使用是比较好的
标签:10,malloc,管理,int,释放,free,动态内存,NULL From: https://blog.csdn.net/weixin_65994469/article/details/144381570