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++知识库]动态内存分配

前言:

什么是动态内存分配?

所谓动态内存分配,就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。 动态内存的好处是归纳为8个字:用时分配,不用释放!”

堆和栈有什么区别?

栈区内存由系统分配和释放;堆区内存由程序员掌控。

程序启动时会为栈区分配一块大小适当的内存,再向这块已有内存中写入数据时,不会涉及内存的分配和释放,所以栈内存的分配效率要高于堆。
?

1.动态内存分配函数的介绍及注意事项:

malloc()

原型:void*?malloc?(size_t?size);

作用:在堆区分配?size?字节的内存空间。

返回值:成功返回分配的内存地址,失败则返回NULL。

注意:分配内存在动态存储区(堆区),手动分配,手动释放,申请时空间可能有也可能没有,需要自行判断,由于返回的是void*,需要手动强制类型转换。

calloc()

原型:void*?calloc(size_t?n,?size_t?size);

功能:在堆区分配?n*size?字节的连续空间。

返回值:成功返回分配的内存地址,失败则返回NULL。

注意:第一参数是第二参数的单元个数,第二参数是单位的字节数。

realloc()

原型:void*?realloc(void?*ptr,?size_t?size);

功能:对?ptr?指向的内存重新分配?size?大小的空间,size?可比原来的大或者小,还可以不变。

返回值:成功返回更改后的内存地址,失败则返回NULL。

free()

原型:void?free(void*?ptr);

功能:释放由?malloc()、calloc()、realloc()?申请的内存空间。

注意!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

每个内存分配函数必须有free函数,释放后不能再次使用被释放的内存。

分配内存最好使用sizeof,用来判断数据类型长度的单目操作符。因为程序移植时,不同的操作系统,同一数据类型的长度可能不一样。

free()函数不能改变指针的值,所以当指针初始化时,尽量声明为NULL。

?

2.动态内存分配函数的使用

1.malloc

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(sizeof(int) * 4);
}

在这里我们在堆上开辟了4个整型的空间,由于malloc这个函数返回的是void*所以我们需要将其强转为int*。

如何操作这4个整型的空间了

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)malloc(sizeof(int) * 4);
	if (p != NULL)//防止动态内存分配失败
	{
		for (int i = 0; i < 4; i++)
		{
			p[i] = i;
		}
		for (int j = 0; j < 4; j++)
		{
			printf("%d ", p[j]);
		} 
	}
	return 0;
}

运行结果:

?操作的方法和数组类似

但特别要注意的是要对malloc返回的指针进行检查,确保他不是空指针

2.calloc 这个函数的使用方法类似

我们可以看看他的函数原型

void*?calloc(size_t?n,?size_t?size)

第一个参数是个数,第二个参数每个元素所占的大小。注意calloc会将开辟好的空间赋初始值0

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int* p = (int*)calloc(4, sizeof(int));
	if (p != NULL)//防止动态内存分配失败
	{
		for (int i = 0; i < 4; i++)
		{
			printf("%d ", p[i]);//打印p所指向空间的内容
		}
	}
free(p);
	return 0;
}

运行结果:

其他用法与malloc基本相同?

?3.realloc用于调整调整分配的空间

#include<iostream>
using namespace std;
#include<stdlib.h>
#include<string>
int main()
{
?? ?int* p = (int*)malloc(sizeof(int));
?? ?
?? ?int* str =(int* ) realloc(p, 2?* sizeof(int));

?? ?if (str != NULL)
?? ?{
?? ??? ?p = str;
?? ??? ?for (int i = 0; i < 2; i++)
?? ??? ?{
?? ??? ??? ?p[i] = i;
?? ??? ?}
?? ??? ?for (int i = 0; i < 2; i++)
?? ??? ?{
?? ??? ??? ?cout << p[i] << endl;
?? ??? ?}

free(str);
?? ?}

?? ?return 0;


}

运行结果:

?

free用于释放动态内存开辟的空间,如果传给free的是空指针,那么free将什么也不做。

总结:

free的参数要么是NULL,要么是一个先前从malloc/calloc/realloc返回的值。向free传递一个NULL参数不会产生任何影响。

这些函数维护一个可用内存池,当一个程序另外需要一些内存时,就调用malloc函数,malloc从内存池中提取一块合适的内存,并向该程序返回一个指向这块内存的指针。这块内存此时并没有以任何方式进行初始化。如果对这块内存进行初始化非常重要,要么自己动手初始化,要么使用calloc函数。

常见的动态内存分配错误:

1.对空指针解引用

2.对分配内存进行操作时越界

3。释放并非动态内存分配内存

4. 试图释放动态内存分配的一部分

5.一块动态内存已经释放了仍然使用

野指针:

前面提到,指针消亡,并不意味着其所指向的内存会被自动释放,同样,释放动态内存,并不意味着指针会消亡,也不意味着指针的值会改变

//假设p是代码块内声明的局部指针变量,在代码块执行完毕退出时,p自动消亡,但p指向的大小为8、类型为int的内存空间不会释放掉。?//代码退出后,程序无法再通过指针p释放所申请的动态内存,这块内存已经“泄露——————内存泄漏?int?*p=(int*)malloc(sizeof(int));...?//运行以后,指针p非但不会消亡,其值还会保持不变,并不会变为null。此时使用if(指针!=null)进行处理也无法起到防错作用。?

解决方法:指针被free或者delete后,一定要置为null,没有置为null的指针常称为”野指针“。

下列两种情况也可以称为**”野指针“**:

1)未初始化指针

任何指针变量刚创建时,其内容是随机的,在内存中乱指一通。因此,使用指针前,一定要对其初始化。在声明的同时初始化或赋值,使其指向合法的内存。对于无处可指的指针变量,也要将其赋值/初始化为null,也就是空指针。

2)指向临时变量的指针

当前代码块执行完毕后,代码块中声明的临时变量(包括函数调用时的参数)都自动消亡,其占用的内存空间(栈内存)也被内存管理器收回。

此时,指向这些临时变量的指针便没有意义,使用这些指针会给程序造成不可预料的结果。



?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-30 11:45:05  更:2021-09-30 11:47:13 
 
开发: 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年12日历 -2024/12/29 4:38:54-

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