C++中用于动态内存的new和delete操作符

文章目录

  • 1、动态分配内存的应用
  • 2、动态分配内存与分配给普通变量的内存有什么不同?
  • 3、C++ 中如何分配/释放内存
  • 4、new 操作符
    • 4.1 使用new的语法
    • 4.2 初始化内存
    • 4.3 分配内存块
    • 4.4 普通数组声明 Vs 使用new
    • 4.5 如果运行时没有足够内存可用怎么办?
  • 5、delete 操作符

C/ C++中的动态内存分配是指由程序员手动执行内存分配。动态内存分配是在堆上进行,非静态变量和局部变量在栈上分配内存。

1、动态分配内存的应用

  • 动态分配内存的一种用途是分配可变大小的内存,这对于编译器分配的内存来说是不可能的,除非是可变长度的数组。
  • 最重要的用途是提供给程序员的灵活性。无论何时需要或不再需要,我们都可以自由地分配和释放内存。这种灵活性在很多情况下都很有用。例子有链表、树等。

2、动态分配内存与分配给普通变量的内存有什么不同?

普通变量 int achar str[10] 等的内存是自动分配和释放的。对于像“int *p = new int[10]”这样动态分配的内存,当不再需要内存时,释放内存是程序员的责任。如果程序员不释放内存,就会导致内存泄漏(直到程序终止才释放内存)。

3、C++ 中如何分配/释放内存

C语言使用 malloc()calloc() 函数在运行时动态分配内存,使用 free() 函数释放动态分配的内存。C++ 除了支持这些函数,还提供了 new 和 delete 两个操作符,可以更好、更简单地分配和释放内存。

4、new 操作符

new操作符表示在空闲存储区(Free Store)上分配内存的请求。如果有足够的内存可用,new运算符会初始化内存,并将新分配的已经初始化的内存的地址返回给指针变量。

4.1 使用new的语法

pointer-variable = new data-type;

这里的指针变量是data-type类型的指针。数据类型可以是任何内置数据类型(包括数组),也可以是任何用户定义数据类型(包括结构体和类)。

例子:

// Pointer initialized with NULL
// Then request memory for the variable
int *p = NULL; 
p = new int;   

            OR

// Combine declaration of pointer 
// and their assignment
int *p = new int; 

4.2 初始化内存

也可以使用new操作符初始化内置数据类型的内存。对于自定义数据类型,需要一个构造函数(输入数据类型)来初始化值。下面是这两种数据类型初始化的例子:

语法:

pointer-variable = new data-type(value);

例子:

int* p = new int(25);
float* q = new float(75.25);

// Custom data type
struct cust
{
	int p;
	cust(int q) : p(q) {}
	cust() = default;
	//cust& operator=(const cust& that) = default;
};

int main()
{
	// Works fine, doesn’t require constructor
	cust* var1 = new cust;

	//OR

	// Works fine, doesn’t require constructor
	var1 = new cust();

	// Notice error if you comment this line
	cust* var = new cust(25);
	return 0;
}

4.3 分配内存块

还可以使用new运算符来分配一个类型为data type 的内存块(一个数组)

语法:

pointer-variable = new data-type[size];

其中 size(变量) 指定了数组中元素的个数。

例子:

int *p = new int[10]

动态地为连续10个 int 类型的整数分配内存,返回一个指向数组的第一个元素的指针,该元素被赋值为 p(指针)。p[0] 表示第1个元素,p[1] 表示第2个元素,以此类推。

在这里插入图片描述

4.4 普通数组声明 Vs 使用new

普通数组声明和使用 new 分配内存块是有区别的。最重要的区别是,普通数组是由编译器释放内存的(如果数组是局部的,那么函数返回或完成时释放)。但是,动态分配内存的数组只有当程序员释放或程序终止时才会释放,否则就一直占用该内存。

4.5 如果运行时没有足够内存可用怎么办?

如果堆中没有足够内存可供分配,new 操作就会通过抛出一个 类型为std::bad_alloc 异常来表示失败,除非 new 操作符使用了 “nothrow”,这种情况下它会返回一个 NULL 指针。因此,在使用 new 创建的指针前最好先进行检查。

int *p = new(nothrow) int;
if (!p)
{
   cout << "Memory allocation failed\n";
}

5、delete 操作符

因为释放动态分配的内存是程序员的责任,所以C++语言为程序员提供了 delete 操作符。

语法:

// Release memory pointed by pointer-variable
delete pointer-variable;  

此处的指针变量指向的是由 new 创建的数据对象。

例子:

delete p;
delete q;

要释放指针变量指向的动态分配内存的数组,可以使用以下形式的delete:

// Release block of memory 
// pointed by pointer-variable
delete[] pointer-variable;  

Example:

   // It will free the entire array
   // pointed by p.
   delete[] p;

完整例子源码:

// C++ program to illustrate dynamic allocation
// and deallocation of memory using new and delete
#include <iostream>
using namespace std;

int main ()
{
	// Pointer initialization to null
	int* p = NULL;

	// Request memory for the variable
	// using new operator
	p = new(nothrow) int;
	if (!p)
		cout << "allocation of memory failed\n";
	else
	{
		// Store value at allocated address
		*p = 29;
		cout << "Value of p: " << *p << endl;
	}

	// Request block of memory
	// using new operator
	float *r = new float(75.25);

	cout << "Value of r: " << *r << endl;

	// Request block of memory of size n
	int n = 5;
	int *q = new(nothrow) int[n];

	if (!q)
		cout << "allocation of memory failed\n";
	else
	{
		for (int i = 0; i < n; i++)
			q[i] = i+1;

		cout << "Value store in block of memory: ";
		for (int i = 0; i < n; i++)
			cout << q[i] << " ";
	}

	// freed the allocated memory
	delete p;
	delete r;

	// freed the block of allocated memory
	delete[] q;

	return 0;
}

输出:

Value of p: 29
Value of r: 75.25
Value store in block of memory: 1 2 3 4 5 

时间复杂度: O ( n ) O(n) O(n) n n n给定的内存大小。

注意:

  • delete 可以释放空指针
int *ptr = NULL;
//Work fine!
delete ptr; 
  • 同一个指针不能使用两次delete,这是未定义行为
#include<iostream>
using namespace std;
 
int main()
{
    int *ptr = new int;
    delete ptr;
    //为同一个指针调用两次delete是未定义的行为,任何情况都可能发生,程序可能会crash也可能没有任何问题
    delete ptr;
    return 0;
}

翻译自文章 new and delete Operators in C++ For Dynamic Memory

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/200479.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第二十章Java博客

如果一次只完成一件事情&#xff0c;很容易实现。但现实生活中&#xff0c;很多事情都是同时进行的。Java中为了模拟这种状态&#xff0c;引入了线程机制。简单地说&#xff0c;当程序同时完成多件事情时&#xff0c;就是所谓的多线程。多线程应用相当广泛&#xff0c;使用多线…

喜报 | 再获影响力产品奖!擎创科技实力亮相GOPS全球运维大会

10月26日-27日&#xff0c;为期两天&#xff0c;共1100余人签到的 GOPS 全球运维大会 2023 上海站已经圆满落幕。 此次会议的“2023 IT技术领导力年度颁奖典礼”中&#xff0c;擎创夏洛克AIOps数智运维管理平台凭借成熟的产品能力及广泛且优异的落地实践效益&#xff0c;得到了…

记 Doris 回归测试S3导入load_parallelism > 1

增加load_parallelism > 1的S3导入用例&#xff0c;测试导入时切分输入文件的逻辑。 这里有几个隐性的问题点&#xff08;坑&#xff09;&#xff1a; 1、导入的文件一定要大&#xff0c;一般大于128M&#xff0c;否则&#xff0c;即使设置了 load_parallelism > 1 也不…

AI搜索相关性在网站和APP上的应用

设定场景&#xff1a;您在寻找一件新衣服&#xff0c;所以在浏览最喜欢的网店。您跳到搜索栏上&#xff0c;输入您要找的东西。您期待出现什么结果&#xff1f; 高度准确、相关和即时的结果。 无论在什么网站上搜索&#xff0c;寻找什么&#xff0c;甚至在打错字或使用了错误的…

JAVA进阶之路JVM-3:JVM内存模型,运行时数据区域划分,程序计数器,虚拟机栈,本地方法栈,堆,元空间,字符串常量池

JVM内存模型 对于 Java 程序员来说&#xff0c;在虚拟机自动内存管理机制下&#xff0c;不再需要像 C/C 程序开发程序员这样为每一个操作去写对应的 delete / free 操作&#xff0c;不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序把内new存控制权利交给JVM虚拟机。一旦…

从源码解析Containerd容器启动流程

从源码解析Containerd容器启动流程 本文从源码的角度分析containerd容器启动流程以及相关功能的实现。 本篇containerd版本为v1.7.9。 更多文章访问 https://www.cyisme.top 本文从ctr run命令出发&#xff0c;分析containerd的容器启动流程。 ctr命令 查看文件cmd/ctr/comman…

高档建筑覆膜板,胶水足表面光滑

在建筑材料行业&#xff0c;选择高质量的建筑覆膜板至关重要。贵港市能强优品木业是专业从事建筑覆膜板生产销售25年的源头工厂。这家工厂一直以来致力于生产出色的覆膜板&#xff0c;以确保建筑物外观精美&#xff0c;持久耐用。 无论是商业大楼还是家庭住宅&#xff0c;外墙装…

气膜建筑助力体育场馆快速普及

传统的室内体育馆投入资金庞大&#xff0c;建设强度高&#xff0c;建设周期漫长。而气膜体育馆的出现&#xff0c;不仅显著降低了建设成本和缩短了建设周期&#xff0c;更符合节能环保的需求&#xff0c;成为推动场馆快速普及的创新建筑形式。 对于校园设施的建设而言&#xff…

可以免费使用的Axure在线版来了

Axure作为一种功能强大的原型设计工具&#xff0c;一直受到设计师的青睐。然而&#xff0c;其高昂的价格可能成为一个门槛&#xff0c;限制了一些设计师的选择。但不用担心&#xff0c;现在有一个免费的Axure在线工具即时设计&#xff0c;功能更完整&#xff0c;更划算&#xf…

『 MySQL数据库 』插入查询结果

文章目录 &#x1f39f;️ 前言&#x1f39f;️ 创建一张结构相同的表&#x1f39f;️ 表内插入查询结果&#x1f3ab; 对表内数据进行去重&#x1f3ab; 配合ORDER BY排序后以及LIMIT分页对数据进行插入 &#x1f39f;️ 前言 在MySQL数据库中不仅可以直接根据字段类型等对数据…

信而泰 SSL测试方法介绍

[本文介绍在ALPS平台上进行SSL测试的内容和方法] 什么是SSL SSL全称是Secure Sockets Layer&#xff0c;指安全套接字协议&#xff0c;为基于TCP的应用层协议提供安全连接&#xff1b;SSL介于TCP/IP协议栈的第四层和第五层之间&#xff0c;广泛用于电子商务、网上银行等。 SSL…

String你知道多少细节(含面试题)

1 字符串初始化 常见的初始化方式有以下3种 public static void main(String[] args) {String s1 "abc";System.out.println(s1);String s2 new String("abc");System.out.println(s2);char[] s3 {a,b,c};System.out.println(s3);} 【注意】 1.Strin…

【带头学C++】----- 八、C++面向对象编程 ---- 8.10 函数的默认参数

8.10 函数的默认参数 C在声明函数原型的时可为一个或者多个参数指定默认(缺省)的参数值&#xff0c;当函数调用的时候如果没有指定这个值&#xff0c;编器会自动用默认值代替。 通过为函数参数指定默认值&#xff0c;可以在调用函数时省略相应的参数&#xff0c;而该参数将使用…

自定义Windows服务启动失败

文章目录 自定义Windows服务启动失败报错内容解决方案管理员身份运行cmd进入到InstallUtil.exe的路径&#xff0c;使用cd命令。使用InstallUtil.exe工具安装服务。 自定义Windows服务启动失败 报错内容 “无法从命令行或调试器启动服务&#xff0c;必须首先安装Windows服务(使…

TikTok区块链实践:数字社交媒体的去中心化未来

随着区块链技术的日渐成熟&#xff0c;数字社交媒体行业也在探索如何整合区块链&#xff0c;以推动去中心化发展。在这一潮流中&#xff0c;TikTok作为全球领先的短视频平台&#xff0c;积极实践区块链技术&#xff0c;探索数字社交媒体的未来。本文将深入探讨TikTok的区块链实…

PHP项目用docker一键部署

公司新项目依赖较多&#xff0c;扩展版本参差不一&#xff0c;搭建环境复杂缓慢&#xff0c;所以搭建了一键部署的功能。 docker-compose build 构建docker docker-compose up 更新docker docker-compose up -d 后台运行docker docker exec -it docker-php-1 /bin/bas…

第13关 解决K8s中Ingress Nginx控制器无法获取真实客户端IP的问题

------> 课程视频同步分享在今日头条和B站 大家好&#xff0c;我是博哥爱运维。 这节课带大家探索并分享最全面的解决在使用Kubernetes&#xff08;K8s&#xff09;和Ingress-Nginx-Controller中无法获取客户端真实IP问题的视频教程&#xff0c;帮助你快速理解并解决这一问…

idea 导入外部包 打包失败

一、在项目中引入jar包 二、pom文件添加 引入外部包 <!--应用第三方包监听文件--><dependency><groupId>jnotify</groupId><artifactId>jnotify</artifactId><version>0.94.0</version><scope>system</scope><…

统信桌面版arm系统安装火狐浏览器和浏览器驱动

一、系统信息 二、下载浏览器和驱动 1、浏览器 https://security.debian.org/debian-security/pool/updates/main/f/firefox-esr/firefox-esr_115.5.0esr-1~deb10u1_arm64.deb 2、驱动 https://github.com/mozilla/geckodriver/releases geckodriver-v0.33.0-linux-aarch6…

如何通过nginx进行反向代理

简单介绍 正向代理 正向代理服务器是一个位于客户端和原始服务器(origin server)之间的服务器&#xff0c;为了能够从原始服务器取得内容&#xff0c;客户端向代理发送一个请求并指定目标(原始服务器)&#xff0c;然后代理向原始服务器转交请求并将获得的内容返回给客户端。正向…