动态内存分配

// 当前内存的使用方式
// 1,创建一个变量
// int a = 10 局部变量 - 栈区(局部变量 函数的形参)
// int G = 10 全局变量 - 静态区(全局变量 静态变量 static修饰的)
// 动态内存 - 堆区(动态内存分配)
//
//void* malloc(size_t size);size内存大小,单位是字节
// 返回的是无类型的void*指针 使用时根据需要进行类型转换 gcc不需要
//用头文件 stdlib.h
//size为0,malloc的行为是标准未定义的,取决与编译器
int main()
{
int* p = (int*)malloc(10 * sizeof(int));//开辟了10个int元素空间并返回地址指针
//如果开辟失败就回返回NULL
if (p == NULL)
{
printf("%s\n", strerror(errno));//打印错误原因
}
else
{
//正常使用
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;//解引用并赋值
}
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));//打印
}
}
//void free(void* ptr);ptr是无类型指针的
//ptr指向的空间不是动态开辟的,那free的行为是未定义的
//ptr为NULL时,函数什么事都不做
free(p);//释放动态开辟的空间,此时p的地址还在,为防止恶意破坏
p = NULL;//给它赋予空指针
//当动态申请的空间不再使用时,还给操作系统
return 0;
}
//
//
//void* calloc(size_t num, size_t size);num为元素的个数,
//size是元素大小,单位是字节 并把元素初始化为0
//返回无类型的void*指针,根据需要进行类型转换
//开辟空间失败 返回NULL

//void* realloc(void* ptr, size_t size);调整动态内存的大小
// ptr 为已经开辟的动态空间
// size 新空间的大小 单位是字节
// 返回无类型的void*指针,根据需要进行类型转换
//
//realloc让动态内存开辟更加灵活
//注意事项:
// 1,需要调整的空间大小在闲置的连续空间大小范围内,可以用原来开辟空间的地址
// 2,如果超出闲置的连续空间大小范围,则重新开辟一个符合要求的空间
// 并拷贝原空间的内容,释放原空间,返回一个新地址
// 3,如果调整失败了,返回NULL,就不能用原指针来接收,
// 解决办法(增加新指针判断其是否为空指针,然后可以赋值给原指针)
//
int main()
{
int* p = (int*)calloc(5, sizeof(int));
if (p == NULL)
{
printf("%s\n", strerror(errno));
}
else
{
//正常使用
int i = 0;
for (i = 0; i < 5; i++)
{
*(p + i) = i;//解引用并赋值
}
for (i = 0; i < 5; i++)
{
printf("%d ", *(p + i));//打印
}
}
int*p2 = (int*)realloc(p, 64);
if (p2 != NULL)
{
p = p2;
}
int i = 0;
for (i = 0; i < 16; i++)
{
*(p + i) = i;//解引用并赋值
}
for (i = 0; i < 16; i++)
{
printf("%d ", *(p + i));//打印
}
free(p);
p = NULL;

return 0;
}

//动态内存分配常见错误
int main()
{
int* p = (int*)realloc(NULL, 40);//当已开辟空间为NULL,此时等价于malloc
//int* p = (int*)malloc(40);
//1,万一malloc失败了,p就被赋予NULL
// 会对NULL的解引用操作,所以要增加判断是否为空指针
//2,操作时会发生越界访问
//3,对非动态空间进行free()
//4,使用free释放动态开辟空间的一部分
//5,对同一块动态空间多次释放
//6,对动态开辟空间忘记释放(内存泄漏)
//
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 0;
}
int i = 0;
//越界访问
for (i = 0; i <= 10; i++)
{
//*(p + i) = i;
*p++ = i;//p指向的地址会发生变化,导致free释放部分空间
}

free(p);
p = NULL;
free(p);//p已置空指针 再次free不进行任何操作
return 0;
}

posted @   小蠕虫  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示