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++知识库 -> 【学习笔记之菜Dog学C】动态内存管理 -> 正文阅读

[C++知识库]【学习笔记之菜Dog学C】动态内存管理

一、为什么存在动态内存管理

??内存分为三个区,栈区、堆区和静态区(也被叫做数据段)。栈区用来存放局部变量、函数形参等临时变量;堆区用来进行动态内存开辟;静态区用来存放全局变量、静态变量等。
??形如int val = 20;char arr[10] = {0};的内存开辟方式是在栈空间上开辟的, 它空间开辟大小是固定的,并且在申明数组的时候,必须指定数组的长度,它所需要的内存在编译时分配。
??但是有时我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了,这时候就只能试试动态存开辟了。
在这里插入图片描述


二、动态内存介绍

1、malloc函数和free函数

  1. malloc函数介绍
    在这里插入图片描述

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针;
如果开辟成功,则返回一个指向开辟好空间的指针;
如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查;
返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定;
如果参数size为0,malloc的行为是标准是未定义的,取决于编译器。

  1. free函数介绍
    在这里插入图片描述

C语言提供了另外一个函数free,专门是用来做动态内存的释放和回收的;
如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的;
如果参数 ptr 是NULL指针,则函数什么事都不做。

  1. 代码实例
int main() {
	//假设开辟10个整型空间 - 10* sizeof(int)
	//动态内存开辟空间
	int* p = (int*)malloc(10 * sizeof(int));//void*
	//使用这些空间的时候
	if (NULL == p) {
		//printf + strerror
		perror("main");//main:xxxxxxxxxxxxx
		return 0;
	}
	//使用
	int i = 0;
	for (i = 0; i < 10; i++) {
		*(p + i) = i;
		printf("%d\n", *(p + i));
	}
	for (i = 0; i < 10; i++) {
		printf("%d ", p[i]);//p[i] --> *(p + i)
	}
	//回收空间
	free(p);
	p = NULL;//手动把p置为NULL,防止访问越界在,造成野指针

	return 0;
}

??malloc基本上和free是成对出现的。

2、calloc函数

  1. calloc函数介绍
    在这里插入图片描述

函数的功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0;
与函数malloc的区别只在于calloc会在返回地址之前把申请的空间的每个字节初始化为全0。

在这里插入图片描述
在这里插入图片描述

  1. 代码实例
int main() {
	int* p = calloc(10, sizeof(int));

	if (NULL == p)
		return 1;
	int i = 0;
	for (i = 0; i < 10; i++) {
		printf("%d\n", *(p + i));
	}
	free(p);
	p = NULL;

	return 0;
}

3、realloc函数

  1. realloc函数介绍
    在这里插入图片描述

ptr 是要调整的内存地址;
size 调整之后新大小;
返回值为调整之后的内存起始位置;
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到 新 的空间;
realloc在调整内存空间的是存在两种情况:
??情况1:原有空间之后有足够大的空间
??情况2:原有空间之后没有足够大的空间

情况一:
在这里插入图片描述
情况二:
在这里插入图片描述

  1. 代码实例
int main() {
	int* p = calloc(10, sizeof(int));

	if (NULL == p) {
		perror("mian");
		return 1;
	}
	//使用
	int i = 0;
	for (i = 0; i < 10; i++) {
		printf("%d\n", *(p + i));
	}
	//这里需要p指向的空间更大,需要20个int函数
	//realloc调整空间
	int* ptr = realloc(p, 20 * sizeof(int));
	if (ptr != NULL) {
		p = ptr;
	}

	free(p);
	p = NULL;

	return 0;
}

三、常见动态内存错误

  1. 对NULL指针进行解引用操作
void test()
{
	int* p = (int*)malloc(INT_MAX / 4);
	*p = 20;//如果p的值是NULL,就会有问题
	free(p);
}
  1. 对动态开辟的空间越界访问
void test()
{
	int i = 0;
	int* p = (int*)malloc(10 * sizeof(int));
	if (NULL == p)
	{
		exit(EXIT_FAILURE);
	}
	for (i = 0; i <= 10; i++)
	{
		*(p + i) = i;//当i是10的时候越界访问
	}
	free(p);
}
  1. 对非动态开辟的内存使用free释放
void test()
{
	int a = 10;
	int* p = &a;
	free(p);//ok?
}
  1. 使用free释放一块动态开辟内存的一部分
void test()
{
	int* p = (int*)malloc(100);
	p++;
	free(p);//p不再指向动态内存的起始位置
}
  1. 对同一块动态内存多次释放
void test()
{
	int* p = (int*)malloc(100);
	free(p);
	free(p);//重复释放
}
  1. 动态开辟内存忘记释放,导致内存泄漏
void test()
{
	int* p = (int*)malloc(100);
	if (NULL != p)
	{
		*p = 20;
	}
}
int main()
{
	test();
	while (1);
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:25:04  更:2022-08-06 10:25:47 
 
开发: 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年11日历 -2024/11/23 12:53:49-

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