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语言动态内存!

为什么存在内存分配

我们之前学的内存分配,都是直接开辟内存。但是这样有一个问题:我们开辟的内存是大了还是小了,会不会浪费,会不会不够用。有的程序只有在运行的时候才知道要用多少空间。所以为了解决这样的问题,我们就有了内存的动态开辟。

动态内存都是在堆区上面的,外面操作动态内存的,malloc free calloc realloc 也都是对堆区的内存进行操作。

malloc 开辟空间 free 释放空间

malloc

malloc 是C语言提供的动态内存开辟函数。

viod* malloc(size_t size);

malloc 申请的是连续的空间。如果开辟成功,那么返回的就是开辟的内存的起始地址。如果开辟失败,就返回 NULL 。返回值的类型是 void* 因为 malloc 不知道开辟的内存是什么类型。所以我们使用的时候,可以强制类型转换一下。转换为我们要使用的类型。例如:我们开辟整型内存。

int* p = (int*)malloc(10*sizeof(int));

free

free 就是对开辟的堆区空间进行释放。每次 free 释放内存之后,一定要把指针变量置为 NULL 防止出现野指针。用法如下:

int* p = (int*)malloc(10*sizeof(int));
free(p);
p = NULL;

使用一个变量来开辟空间,这里使用一个变量 num 来开辟一段动态空间:

int main()
{
	int num = 0;
	scanf("%d", &num);
	int* ptr = (int*)malloc(num * sizeof(int));
	if (ptr != NULL)
	{
		int i = 0;
		for (i = 0; i < num; i++)
		{
			*(ptr + i) = i + 1;
		}
		for (i = 0; i < num; i++)
		{
			printf("%d ", *(ptr + i));
		}
	}
	free(ptr);
	ptr = NULL;
	return 0;
}

在这里插入图片描述
这里就是通过输入一个数 num 然后开辟相应的内存空间。并且赋值为 1 - 10 。

calloc 开辟空间

C语言也提供了另外一个开辟空间的函数,calloc 与 malloc 不同的是,calloc 开辟空间之后,在返回空间的起始地址之前,把所有空间全部赋值为 0 。示例:

//C语言文档给的代码
void* calloc (void* ptr, size_t size);
int main()
{
	int* p = (int*)calloc(10, sizeof(int));
	if (NULL != p)
	{
		//使用空间
	}
	free(p);
	p = NULL;
	return 0;
}

在这里插入图片描述
在这里插入图片描述
由第二张图片就可以看到,p 所指向的空间,全部被置为了 0 。如果我们对申请的内存有初始化的需求,就可以使用 calloc 来进行初始化。

realloc 管理内存

有时候我们会发现申请的内存大了或者小了,所以就用到 realloc 来对内存大小进行灵活的调整。如果 realloc 调整内存失败后,也会返回空指针。C语言给的函数模型是这样:

void* realloc (void* ptr, size_t size);

ptr 是要调整的内存地址。
size 是要调整的大小。
返回值是调整大小之后的内存起始位置。

realloc 调整内存的两种情况

情况1:原有空间之后有足够大的空间

当原来的空间后面有足够大的空间的话,就连着原有空间继续开辟,就是下面图片这样的情况。就是原有内存之后直接追加空间,原来空间的数据不发生变化,并且返回值的地址还是原来的地址。
在这里插入图片描述

原有空间之后没有足够大的空间

当原来空间的后面没有足够大的空间的话,其扩展的方法就是:再找一块空间,可以放得下原有的空间的内容和新开辟的空间,并且返回新的内存地址。不过在传回新的地址之前。会把原来的那段空间 free 掉。不能用原来的指针去接收返回值,因为如果开辟失败,那么原来的指针也变成 NULL 了。就是下图这样:
在这里插入图片描述

realloc 使用代码示例

int main()
{
	int* p = (int*)calloc(10, sizeof(int));
	//空间不够 增加到 20个 int
	int* ptr = (int*)realloc(p, 20 * sizeof(int));
	if (ptr != NULL)
	{
		p = ptr;
	}
	else
	{
		//ptr是空指针 返回-1
		return -1;
	}
	//增容成功
	for (int i = 10; i < 20; i++)
	{
		*(ptr + i) = i;
	}
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", *(ptr + i));
	}
	free(ptr);
	ptr = NULL;
	free(p);
	p = NULL;
	return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-03 16:54:12  更:2021-10-03 16:54:19 
 
开发: 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/24 0:40:20-

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