IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c语言动态内存分配——基本必会知识 -> 正文阅读

[C++知识库]c语言动态内存分配——基本必会知识

为什么要动态内存空间分配

有时候我们需要的空间只有在程序运行的时候才知道,那么数组的固定开辟空间的方式不能满足需求。

动态内存分配函数

1.malloc函数和free函数

头文件:#include<stdlib.h>
使用格式:malloc(总字节数);
malloc的返回值类型为:void*
所以malloc函数并不知道开辟空间的类型,具体类型要靠使用者进行强制类型转换
作用:向内存申请n个空间,申请成功后返回申请的空间的首元素的地址

	int* p =(int*) malloc(11);
	if (p == NULL)
		printf("%s\n", strerror(errno));
	else
	{
		for (int i = 0;i < 10;i++)
			*(p + i) = i;
		for (int i = 0;i < 10;i++)
			printf("%-5d", *(p + i));
	 }
	//当动态申请的空间不再使用时
    //就可以将内存还的操作系统
	free(p);
	p=NULL;

当申请的空间不再使用时,应该主动将申请的空间还给操作系统。
否则会一直占用空间到程序结束。如果在程序的结尾就没有太大的必要,因为在程序结束时会自动返还空间。
虽然指针p指向的空间被释放(既空间存储的参数清除),但指针p依然指向这份空间的地址,使用p依然可以找到这份空间。为了避免发生错误,在释放p的空间时要将p指向空指针。
malloc函数存在开辟失败的情况,所以malloc的返回值一定要检查。
free函数释放的空间必须是动态内存开辟的空间
free函数和malloc函数的头文件都是<stdlib.h>
malloc函数与free函数要成对使用

2.calloc函数

头文件:#include<stdlib.h>
使用格式:calloc(元素个数,每个元素的大小);
calloc的返回值类型为:void*
所以calloc函数并不知道开辟空间的类型,具体类型要靠使用者进行强制类型转换
作用:向内存申请n个空间并初始化为0,申请成功后返回申请的空间的首元素的地址
calloc函数与free函数要成对使用

3.realloc函数

头文件:#include<stdlib.h>
使用格式:realloc(要调整的内存地址,调整之后的空间大小);
realloc的返回值类型为:void*
所以realloc函数并不知道开辟空间的类型,具体类型要靠使用者进行强制类型转换
作用:调整动态开辟内存空间的大小

int* p2 = (int*)realloc(p, 40);
if(p2!=NULL{   //先检查是否追加成功,如果追加成功则覆盖在原指针上
  p=p2;
}
free(P);
p=NULL;

realloc函数作用机理图:
在这里插入图片描述

这时我们想要追加新的空间,有两种可能:
1.原先空间后面的空间足够,则在原先空间后面追加空间即可,那么返回原来空间的地址。

在这里插入图片描述

2.原先空间后面的空间不足,则新找一整块足够的空间重新开辟,并将原先空间中的数值复制过去,
复制后会自动释放原来的空间,那么返回新空间的地址。
在这里插入图片描述

realloc函数注意事项:
1如果p指向的空间之后有足够的内存空间,则字节追加,后返回p。
2如果p指向的空间之后没有足够的内存空间,则realloc函数和重新找一个新的内存区域来开辟一块满足需求的空间,并且将原来空间的数据拷贝回来,释放旧的内存空间,最后返回新开辟的内存空间的地址
3.倘若需要开辟的空间过大,realloc函数可能开辟失败,如果开辟失败,那函数将返回一个空指针。那么结果是不仅开辟失败,而且原来的开辟的地址丢失,无法查找,所以realloc函数的返回值一般不会直接放到原指针中。
realloc函数与free函数要成对使用

常见的动态内存分配错误

1.对NULL指针的解引用操作

	int* p = (int*)malloc(40);
	//万一malloc失败了,p就被赋值为NULL
	for (int i = 0;i < 10; i++)
		*(p + i) = i;
	free(p);
	p = NULL;
避免方法:
在使用动态内存分配函数后一定要对返回值进行检查。

2.对动态开辟的内存的越界访问

	int* p = (int*)malloc(20);
	//只开辟了五个元素
	if (p == NULL)
		return 0;
	else
		for (int i = 0;i < 10;i++)
	//访问了十个元素,产生越界访问
			*(p + i) = i;
	free(p);
	p = NULL;
避免方法:
养成在malloc函数填写参数时写(元素个数*每个元素的大小),明确总元素个数。
例如malloc(5*sizeof(int))

3.对非动态开辟内存使用free释放

	//常规开辟的内存存放在栈区
	//而动态开辟内存存放在堆区
	int a = 10;
	int* p = &a;
	*p = 20;
	free(p);
	p = NULL;
		常规开辟的内存存放在栈区
     	动态开辟的内存存放在堆区
     	free函数无法释放常规开辟的内存空间

4.使用free释放动态开辟内存的一部分

int* p = (int*)malloc(40);
	if (p == NULL)
		return 0;
	else
		for (int i = 0;i < 10;i++)
			*p++ = i;
	//释放空间
	free(p);
	//因为p++,p所指向的空间地址已发生变化
	//free无法释放动态开辟空间的一部分
	p = NULL;
避免方法:
应在程序中避免让指针移动,找到代替代码。释放时注意指针所指向的位置
例如:在循环中(*p++)=*(p+i)

5.对同一块动态内存多次释放

int* p = (int*)malloc(40);
	if (p == NULL)
		return 0;
	else
		for (int i = 0;i < 10;i++)
			*(p+ i) = i;
	free(p);
	//......
	free(p);
	p = NULL;
避免方法:
1.团队中谁开辟谁释放。
2.一定要在free函数后面加p=NULL,这样即使后面再释放p也对程序无影响。

6.对动态开辟的内存忘记释放(内存泄漏)

	while (1)
	{
		malloc(1);
	}
如果不释放内存,那么对于这段空间自己不使用,而别人也无法使用,
则会白白占用大量内存,损耗性能。
避免方法:开辟使用后及时检查是否释放
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 20:56:54  更:2022-10-22 21:00:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 3:41:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码