C++中new、delete 与new[]、delete[]

news/2024/5/20 8:53:39 标签: , 对象, , 内存泄露, 指针
在C++中,申请内存,使用new或者new[],在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。

关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据型分配和回收空间;(2) 为自定义型分配和回收空间。

先看以下例子:

#include<iostream>
#include<new>

using namespace std;

int main()
{
	//new int []
	int b[]={1,2,3,4};

	int *c=new int [10];

	memset(c,0,10*sizeof(int));

	memcpy(c,b,10*sizeof(int));

	for(int i=0;i<4;i++)
	{
		cout<<*(c+i)<<" ";
	}
	cout<<endl;

	delete [] c;//这时候delete c是没有区别的

	char *str=new char;

	char s='a';

	*str=s;    //给内存赋值 似于上面的memcpy函数的功能
	//str=&s;  //让指针指向桟内存,错误的做法

	cout<<*str<<endl;

	delete str;//这时候delete []str是没有区别的

	system("pause");
	return 0;
}

可以正常运行,在内置的型中,比如int,char,long等delete 和 delte[]是没有区别的,但是如果是自定义的结构或,则不会回收,就会造成内存泄露


再看第二种情况:

#include <iostream>
#include<new>

using namespace std;

class T 
{
public:

  T() { cout << "constructor" << endl; }

  ~T() { cout << "destructor" << endl; }
};

int main()
{
  const int NUM = 3;

  T* p1 = new T[NUM];

  cout<<p1<<endl;

  delete [] p1;

  //delete [] p1;

  T* p2 = new T[NUM];

  cout<<p2<<endl;

  delete [] p2;

  system("pause");
  return 0;
}

运行结果:


结果分析:

从运行结果中我们可以看出,delete p1 在回收空间的过程中,只有 p1[0] 这个对象调用了析构函数,其它对象如 p1[1]、p1[2] 等都没有调用自身的析构函数,这就是问题的症结所在。如果用 delete[],则在回收空间之前所有对象都会首先调用自己的析构函数。 
    基本型的对象没有析构函数,所以回收基本型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于对象数组,只能用 delete[]。对于 new 的单个对象,只能用 delete 不能用 delete[] 回收空间。 
    所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用


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

相关文章

JavaWeb-HTTPServletReauest和HTTPServletResponse

2019独角兽企业重金招聘Python工程师标准>>> HttpServletRequest 和 HttpServletResponse Servlet配置方式 1. 全路径匹配以 / 开始 /a /aa/bb localhost:8080/项目名称/aa/bb 2. 路径匹配 , 前半段匹配以 / 开始 &#xff0c; 但是以 * 结束 /a/* /* 其实是一个通配…

flutter版本的玩Android客户端

flutter学习案例 目录介绍 00.项目下载与查看01.项目介绍02.项目优势03.部分功能介绍04.部分截图展示05.版本更新06.flutter系列博客07.感谢08.如何辨别flutter与原生09.关于更多00.项目下载与查看 0.0 项目地址 https://github.com/yangchong2...0.1 下载apk 已经打包好的apk存…

何时需要强制类型转换?

可能运行程序时&#xff0c;大家或多或少出现过编译器报这样的警告&#xff1a; #include<iostream>using namespace std;int main() {int i3;double j3.99;i*j;cout<<i<<endl;//11system("pause");return 0; }warning C4244: “*”: 从“double”…

OneNote发布至博客园

第一步&#xff1a;开启入口 文件--》发送--》发送至博客 在弹出的word文件的对话框中&#xff0c;选择立即注册 第二步&#xff1a;配置上送至博客园的流程 &#xff08;承接上一步&#xff09;在博客的引擎中&#xff1a;选择其他 设置连接账户的用户名密码&#xff0c;连接地…

C++标准库---容器作为形参?

通常&#xff0c;函数不应该有 vector 或其他标准库容器类型的形参。调用含有普通的非引用 vector 形参的函数将会复制 vector 的每一个元素。因此&#xff0c;调用含有普通的非引用vector作为形参的函数&#xff0c;无论效率还是资源利用率&#xff0c;都是极大的浪费。 从避…

【Java菜鸟学习总结】Java基础(关键字、数据类型、运算符、流程控制)

目录 【Java菜鸟学习总结】Java基础&#xff08;关键字、数据类型、运算符、流程控制&#xff09;1、关键字2、保留字3、标识符4、数据类型5、运算符6、程序流程控制【Java菜鸟学习总结】Java基础&#xff08;关键字、数据类型、运算符、流程控制&#xff09; 1、关键字 1.1、用…

Vant Weapp的dialog组件在mpvue小程序中使用注意事项

问题 Dialog组件支持函数调用和组件调用两种形式&#xff0c;而一般的组件仅支持后者。显然&#xff0c;函数调用方式的支持增加了组件使用的灵活性&#xff0c;但是也随之出现另外几个值得注意的问题。 两种方式使用举例 在我的mpvue工程测试中&#xff0c;针对dialog组件我专…

关于函数返回引用的分析?

一、函数返回值和返回引用是不同的函数返回值时会产生一个临时变量作为函数返回值的副本&#xff0c;而返回引用时不会产生值的副本。 1.普通函数返回值 C primer中这样写&#xff1a;函数的返回值用于初始化在调用函数处创建的临时对象。在求解表达式时&#xff0c;如果需要…