首页 > 其他分享 >24new和delete的运算符重载视角

24new和delete的运算符重载视角

时间:2024-01-21 11:33:40浏览次数:22  
标签:malloc 24new 运算符 内存 数组 重载 new delete

new和delete的运算符重载视角

new和malloc对比:

  • malloc按字节开辟内存,返回void*,需要强制类型转换;new开辟内存需要指定类型
  • new在malloc的基础上,还会进行数据的初始化
  • malloc开辟内存失败返回nullptr,new抛出bad_alloc类型的异常

delete和free对比:

  • delete是在free的基础上进行了析构

运算符重载视角

  • 事实上,new是operator new的重载,delete也是operator delete的重载。全局空间下可以重载new和delete。
  • 如何发现程序中的内存泄露?
    • 编写全局作用域的new和delete的运算符重载方法,并自定义一个内存申请与释放的记录表,监视new和delete的记录。
  • new和delete能混用吗?C++为什么可以区分单个元素和数组的内存分配和释放?blog参考
    • 在new对象是,如果对象是单个元素,则直接开辟内存并初始化;如果对象是类对象(且显式定义了析构函数)的数组,则其malloc的空间为4字节+对象数组所需的空间,其中开头4字节用于保存数组长度,不过返回的是数组空间首地址。delete时,delete数组还需free开头四字节的部分。
    • 如果new和delete仅针对简单编译器内置类型做内存开辟和释放,不涉及类对象构造析构,则不会报错
    • 如果new和delete涉及类对象构造析构,且没有配对使用。
      • 将单个对象delete[]:则代码执行会向前探索4字节以获取数组长度,报错。
      • 将数组对delete,则释放第一个元素,不会报错,但存在内存泄漏。
using namespace std;

//先调用operator进行内存开辟,然后自动调用对象的构造函数
void* operator new(size_t size)
{
	void* p = malloc(size);
	if (p == nullptr)
		throw bad_alloc();
	cout << "operator new addr: " << p << endl;
	return p;
}

void* operator new[](size_t size)
{
	void* p = malloc(size);
	if (p == nullptr)
		throw bad_alloc();
	cout << "operator new[] addr: " << p << endl;
	return p;
}

void operator delete(void* ptr)
{
	cout << "operator delete addr: " << ptr << endl;
	free(ptr);
}

void operator delete[](void* ptr)
	{
		cout << "operator delete[] addr: " << ptr << endl;
		free(ptr);
	}

class Test
{
public:
	Test(int data = 10) { cout << "Test()" << endl; }
	~Test() { cout << "~Test()" << endl; }

private:
	int* ptr;
};

int main()
{
	try
	{
		Test* p1 = new Test[6];
		//delete p1;//混用出现问题
		delete []p1;
		int* p = new int[3];
		delete p; //内存泄露,不报错
		int* q = new int(2);
		delete[]q;
	}
	catch (const bad_alloc& err)
	{
		cerr << err.what() << endl;
	}
}

标签:malloc,24new,运算符,内存,数组,重载,new,delete
From: https://www.cnblogs.com/sio2zyh/p/17977657

相关文章

  • 25new和delete重载实现的对象池应用
    new和delete重载实现的对象池应用在类底层维护一个结构体链表,new和delete重载以避免大量重复的new和delete操作。usingnamespacestd;#include<iostream>staticconstintPOOL_ITEM_SIZE=1000000;template<typenameT>classQueue{public: Queue() { _front=_r......
  • 20C++的运算符重载
    C++的运算符重载编译器在做对象运算的时候,会调用对象的运算符重载函数(优先调用成员方法)。如果找不到合适的成员方法,则在全局作用域寻找合适的运算符重载函数.#include<iostream>usingnamespacestd;//复数类classCComplex{private: intmreal; intmimage; //友元函......
  • (11)Powershell赋值运算符(二)
    (11)Powershell赋值运算符(二)上一节介绍了Powershell赋值运算符中的=,+=,-=,详细内容参考这里。本节介绍Powershell赋值运算符中的*=,/=,%=,++,--。1.乘法赋值运算符(*=)乘法赋值运算符(*=)对数字值执行乘法或追加指定数目的变量字符串值副本。如果变量是单个......
  • C# 运算符详解:包含算术、赋值、比较、逻辑运算符及 Math 类应用
    运算符用于对变量和值执行操作。在C#中,有多种运算符可用,包括算术运算符、关系运算符、逻辑运算符等。算术运算符算术运算符用于执行常见的数学运算:intx=100+50;//加法,结果为150inty=x-30;//减法,结果为120intz=x*2;//乘法,结果为300intw=......
  • 细说JavaScript表达式和运算符号(JavaScript表达式和运算符号详解)
    除了简单的表达式还有复杂的表达式,它是由简单表达式构成的,将简单表达式组合成复杂表达式最常见的方法就是使用运算符![细说JavaScript表达式和运算符号详解](https://img-blog.csdnimg.cn/direct/2781400b25be4b38bbf99d0c1b93d169.png)一、表达式表达式分为简单表达式和复杂......
  • powershell中的比较运算符
    操作定义-eq等于-ne不等于-gt大于-ge大于或等于-lt小于-le小于或等于-Like使用 * 通配符进行匹配-NotLike不使用 * 通配符进行匹配-Match匹配指定的正则表达式-NotMatch不匹配指定的正则表达式-Contains确定集合中是否包含指定的值-NotContains确定集合是否不包含特定值-In确定......
  • (10)Powershell赋值运算符(一)
    (10)Powershell赋值运算符(一)上一节介绍了Powershell中的内置变量,细节使劲戳jiaerkuaier。本节介绍Powershell中的赋值运算符,赋值运算符可向一个变量赋予一个或多个值。赋值运算符可以在赋值之前对值执行数值运算。Powershell支持以下赋值运算符。运算符说明备注......
  • (7)Powershell算术运算符
    (7)Powershell算术运算符本系列博客从这一节开始是Powershell的语法知识,在开始学习语法之前,希望你对Powershell有个基本的了解,比如开发工具的使用,面向对象等特性,详细内容使劲戳这里(1)-(6)的内容。本节主要介绍Powershell中的算术运算符。Powershell支持以下算术运算符......
  • Delete d node at nth position【1月17日学习笔记】
    点击查看代码//Deletednodeatnthposition#include<iostream>usingnamespacestd;structnode{ intdata; node*next;};node*A;voidinsert(intx){ node*temp=newnode; temp->data=x; temp->next=NULL; if(A==NULL){ A=temp;......
  • 不可不看的Java基础知识整理,注释、关键字、运算符
    写在开头万丈高楼平地起,要想学好汉语首先学拼音,想学好英语首先学26个字母,对于编程语言来说,一样的道理,要想学好必须先掌握其基础语法和知识,今天我们就来唠一唠Java语言中那些出现频率极高,又很基础的知识点吧!Java中的注释注释的作用:拨云见日!在日常的工作中,总会遇到很多大段的代......