实验环境:(本次探讨所需要的平台和相关软件) 硬件环境:Windows 11 软件环境:Visual Studio 2022
程序的内存模型:c++在执行程序时,将内存划分为4个区域
内存四区意义:不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程
堆区
//例1:
//结果:
//解释:
为什么存在动态内存分配![]()
但是上述的开辟空间的方式有两个特点:
1.空间开辟大小是固定的
2.数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行时才能知道,那数组的编译时开辟空间的方式就不能满足了。这时候就只能试试动态开辟内存了。(在堆上分配)
C++与C中的动态内存分配区别总结:1. new与delete的使用: (1)创建变量
(2)利用 new创建数组
2. malloc与free的使用:
C语言提供了一个动态内存开辟的函数
(1) malloc
原型:void * malloc ( size_t )
这个函数向内存申请一块连续可用的(size_t个字节的)空间,返回这块空间的起始地址
//示例:
动态内存开辟:
![]()
这里需要整型指针来维护malloc返回的指针
C语言提供了另一个函数free,专门是用来做动态内存的释放和回收的
(2)free
函数原型: void free ( void* memblock );
//
示例:
释放空间:
![]()
malloc 和 free都声明在 stdlib.h 头文件中 。举个例子:
![]()
解释:创建 含有num 个元素的整型数组
3. new与malloc区别: 均用于向动态申请一块连续的内存空间: (1) 表格对比辨析
(2) new或者malloc时经常会产生的一些问题: 接下来我们探讨在使用new或者malloc时经常会产生的一些问题:
a)链式结构中为什么不能对指针进行运算(ptr++或者ptr+1等)?
我们知道,通常我们在写链表的时候,对于单链表我们通过访问指针域的next进行下一内存地址的访问,如果是双链表我们通过指针域的front和next分别对前/后指向内存进行访问,那链式结构中为什么不能对指针进行运算(ptr++或者ptr+1等),实际上,链式结构是一个个结点通过指针域连接而成,实质上并不一定是一块连续的存储空间,ptr++或者ptr+1无法找到匹配这段空间大小的记录,所以并不能使用运算符,否则可能造成非法访问. ,此运算只能用于一块连续的存储空间.
b)为什么new(delete)的效率高于malloc(free)? new和malloc都可用于申请动态内存和释放内存。对于非内部数据类型的对象(如自定义数据类型)而言,仅maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,在消亡之前要自动执行析构函数,malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free而new/delete可以。 C++中的new则能完成动态内存分配和初始化工作,以及delete能完成清理与释放内存工作,所以说new的效率高于malloc。
c)自由存储区和堆区? ①自由存储区(free store)是C++中通过new和delete动态分配和释放对象的抽象概念,通过new来申请的内存区域可称为自由存储区. ②堆(heap)C语言和操作系统的术语,堆是操作系统所维护的一块特殊内存,它提供了动态分配的功能,当运行程序调用malloc()时就会从中分配,调用free()归还内存。一般情况下,所有的C++编译器默认使用堆来实现自由存储。
d)new可以分配两种内存: new可以分配两种内存,单个变量的内存/连续的内存: new只有分配单个内存的时候可以同时给该内存赋值(即调用对象的构造函数),分配连续多个内存时是无法同时赋值的
4.delete与free:(1) 表格对比辨析
(2) 问题讨论: a) 如果多次申请空间那么系统是如何做到空间的不重复使用呢? 这是因为,在使用动态内存开辟一段空间之后,系统会在这段空间之前做一个标记(0或1),当new或malloc开辟空间如果遇到标记为0就在此开辟空间,如果标记为1表示该块内存正在被占用,则不开辟. 相应的,当我们不再需要ptr指向的内存时,需要及时释放这块内存,将它归还给系统,否则该块内存一直处于被占用,其他变量无法对其使用,进而造成内存泄漏;当ptr指定的区域被释放以后,标记值会发生变化为0,表示变量ptr不再具有对这块内存的使用权,此时ptr可能指向随机一块内存,所以通常我们需要及时把ptr置为NULL,使其指向一块没有意义的空间,防止ptr非法访问某块内存区域. (2) 释放时需要注意: 先判断该指针是否为NULL,防止重复释放.
(自身掌握知识有限,如有错误的地方或更好的建议,敬请指正!) |