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

news/2024/7/3 12:24:54 标签: 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++ 除了支持这些函数,还提供了 newdelete 两个操作符,可以更好、更简单地分配和释放内存。

new__13">4、new 操作符

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

new_16">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个元素,以此类推。

在这里插入图片描述

new_87">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";
}

delete__101">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给定的内存大小。

注意:

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


http://www.niftyadmin.cn/n/5225724.html

相关文章

如何在langchain中对大模型的输出进行格式化

简介 我们知道在大语言模型中, 不管模型的能力有多强大&#xff0c;他的输入和输出基本上都是文本格式的&#xff0c;文本格式的输入输出虽然对人来说非常的友好&#xff0c;但是如果我们想要进行一些结构化处理的话还是会有一点点的不方便。 不用担心&#xff0c;langchain已…

关于团队管理的一些思考

1、团队&#xff1a;为什么需要团队&#xff0c;一个人或者一群人不行吗&#xff0c;当一个项目需要的能力仅靠个人无法满足时&#xff0c;这时候就需要团队来完成&#xff0c;一群人和一个团队的主要区别就是团队有一个共同的目标&#xff0c;团队成员可以发挥自己的优势一起完…

案例:某电子产品电商平台借助监控易保障网络正常运行

一、背景介绍 某电子产品电商平台是一家专注于电子产品销售的电商平台&#xff0c;拥有庞大的用户群体和丰富的产品线。随着业务规模的不断扩大&#xff0c;网络设备的数量和复杂性也不断增加&#xff0c;网络故障和性能问题时有发生&#xff0c;给平台的稳定运行带来了很大的挑…

Python基础语法之学习数据转换

Python基础语法之学习数据转换 一、代码二、效果 一、代码 #数字转换成字符串 num_str str(11) print(type(num_str))#字符串转整数 numint("11") print(type(num),num)#浮点数转整数 float_num int(11.1) print(type(float_num),float_num)#整数转浮点数 num_flo…

重生之我是一名程序员 45 ——字符串函数(4)

哈喽啊大家晚上好&#xff01;今天呢给大家带来的还是字符串函数之一的strncpy函数。 首先呢还是带大家认识一下它&#xff0c;strncpy函数是C语言标准库中的一个字符串处理函数&#xff0c;用于将一个字符串中的一部分复制到另一个字符串中&#xff0c;可以指定复制的长度。函…

CTF ssrf+pin

什么是pin码 pin码是flask在开启debug模式下&#xff0c;进行代码调试模式所需的进入密码&#xff0c;需要正确的PIN码才能进入调试模式,可以理解为自带的webshell pin码如何生成 pin码生成要六要素 1.username 在可以任意文件读的条件下读 /etc/passwd进行猜测 2.modname 默…

F. Magic Will Save the World

首先积攒了能量打了怪再积攒是没有意义的&#xff0c;可以直接积攒好&#xff0c;然后一次性进行攻击 那么怎么进行攻击了&#xff1f;可以尽量的多选怪物使用水魔法攻击剩余的再用火魔法进行攻击&#xff0c; 也就是只要存在合法的体积&#xff08;即装入背包的怪物的体积之…

接口容灾~

1. 线上cdn缓存 2. 线下indexdb缓存 策略&#xff1a; 请求-> cdn白名单&#xff1f; -no-> 请求 -yes->&#xff08;构建标识cdnUrl&#xff09;数据正常? -> no -&…