网站首页 > 技术文章 正文
动态内存管理 new 和 delete
在软件开发中,需要动态地申请和销毁内存空间。在C语言中是提供了库函数malloc()和free()来分配和撤销内存空间的。但是,使用malloc()函数时必须指定需要申请的内存空间的大小。其调用形式为:
void* p = malloc(size);
其中 size 就是字节数,需要用户指定需要申请内存的字节数。
例如,我们想申请一个内存块,存放一个struct结构体对象。此时,我们可以使用sizeof()运算符来求出struct结构体对象的大小,然后,再调用malloc()来申请内存空间。
C++提供了简单而功能强大的运算符 new 和 delete 来取代 malloc()和 free()函数(为了与C语言兼容,C++仍保留这两个函数)。
new 运算符,用于申请内存空间,使用的一般格式为:
(1) new 类型; --- 申请一个内存块,内存的大小是“类型”占用的字节数。成功,返回申请到内存块的首地址,失败,返回NULL空指针。
(2) new 类型(初始值); --- 申请一个内存块,内存的大小是“类型”占用的字节数,并给内存块存放初始值。成功,返回申请到内存块的首地址,失败,返回NULL空指针。
(3) new 类型[数组长度]; --- 申请一个内存块,内存块是一个数组,数组的元素是“类型”指定的元素类型,在中括号[]中指定数组的长度。成功,返回申请到内存块的首地址,失败,返回NULL空指针。
注意:用 new 分配数组空间时,不能指定初值。
delete 运算符,用于释放内存空间,使用的一般格式为:
(1) delete 指针变量;
(2) delete []数组;
注意:使用new关键字申请的内存空间,需要使用delete关键字释放。如同C语言,使用malloc()函数申请的内存空间,需要使用free()函数来释放。
举例分析如下:
new int; //开辟一个存放整型数据的空间,返回一个指向整型数据的指针;
new int(100); //开辟一个存放整型数据的空间,并指定该整数的初值为100;
new char[16]; //开辟一个存放字符数组的空间,该数组有16个元素,每个元素的类型是char,并返回指向字符类型的指针;
new int[5][6]; //开辟一个存放二维整型数组的空间,该数组大小为5*6个元素;
float *p = new float(168.889); //开辟一个存放实数的空间,并指定该实数的初值为168.889,并将返回指向实型数据的指针,赋给指针变量p;
在上面的举例中,有申请一个float类型大小的内存空间,并存放168.889的初始值。那么,如果要销毁用 new 申请的空间,可以用delete关键字销毁,如下:
delete p;
前面用 new char[16]; 开辟的空间,如果把返回的指针赋给了指针变量 p,如下:
char* p = new char[16];
那么,应该用以下形式的delete 运算符销毁所申请的空间:
delete []p; //在指针变量前面加一个中括号,表示对数组释放内存;
如果由于内存不足等原因,而无法正常分配空间,则 new 会返回一个空指针NULL,用户可以根据该指针的值判断申请分配内存是否成功。如下是测试例子:
程序运行结果如下:
可以看到,执行 new int(16289);代码,就申请int类型的内存空间,并设置16289这个数值。所以,给指针变量pi申请的内存空间,里面存放了16289这个数值。
执行 new char[256]; 此时,申请一个char类型的数组,数组的长度是256个元素。把申请到内存空间地址,设置给指针变量p,然后,给指针变量p指向的地址拷贝字符串。
创建二维数组的操作如下,首先,声明一个二维数组的指针对象:
char (*ps)[128];//定义二维数组,第二维是128个元素;
表示数组的元素是 char 类型,是一个二维数组。数组的第二维是128个元素的长度。第一维的长度不确定,是char*类型。
创建二维数组,如下:
ps = new char[3][128];//创建二维数组;
此时,创建二维数组,第一维是3个元素,第二维是128个元素;第一维中的元素,每个元素是一个128个元素长度的一维数组。
注意:new 和 delete 是运算符(所以,它们可以重载),不是函数,因此执行效率高。malloc()函数要和free()函数配合使用,new和delete配合使用,不能混合使用。
还有,free()和new撤销后(释放内存后)的指针,还保留原来的地址值。所以,为了预防野指针,释放后的指针,应该给其赋NULL值。
因为,释放后的内存块,内存被系统回收!所以,原来保留的内存地址已经被系统回收,不可以再使用!
总结
本章节我们更深一步学习了C++的基础知识,学习了引用的定义和使用,这是C++语言中一个重要的知识点,需要重点掌握。
然后,学习了内联函数的使用,作用域运算的操作,new和delete关键字的使用,这些都是C++语言特性。有了这些C++基础知识之后,我们接下来开始学习C++的面向对象编程,开始学习C++最重要的概念:类的定义和使用。
读者要仔细分析,掌握好每一个知识点,然后,自己总结出对该知识点的理解。自己总结出来的知识,理解才深刻,才是自己掌握的知识。
猜你喜欢
- 2024-12-06 2024年C++编程不再推荐使用的功能你还在在用吗?
- 2024-12-06 C++ memcpy的用法,大数据传输与获取
- 2024-12-06 C++中继承的详细介绍以及多态的使用场景
- 2024-12-06 C++“智能指针”并不智能,因为它也不总是知道内存是如何分配的
- 2024-12-06 C++11精要学习:右值引用与完美转发
- 2024-12-06 C/C++编程笔记:详细讲解丨复制构造函数
- 2024-12-06 C++ map用法总结
- 2024-12-06 C#与C++交互开发系列(四):使用C++/CLI进行互操作
- 2024-12-06 C++的map用法
- 2024-12-06 C++基础语法梳理:内存分配和管理
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)