C++ New和Delete

本文详细介绍了C++中动态内存管理的关键运算符new和delete的用法。new用于在堆上分配内存,返回空间的首地址,而delete则用于释放内存,防止内存泄漏。文章通过示例展示了如何使用new创建和初始化单个变量、数组以及结构体数组,并强调了new与delete必须配对使用的重要性。

 

目录

前言

New

Delete


前言

    new是c++中用于动态申请空间的运算符,malloc也是用于动态申请空间的,但malloc是函数。

New

    new是用来开辟一段新空间的,和一般申明不同的是,new开辟的新空间是在堆上,而申明的变量是在栈上。也就是说,当在局部函数中new出一段新的空间,该段空间在局部函数调用结束后仍然能够使用,可以用来向主函数传递参数。

    new会返回一段空间的首地址,需要用指针来接收。

注意new的叫法:new操作符是关键字,不用加头文件,可重载。

                            操作符new则是一个函数。

    new的使用:

    new是运算符,不需要加头文件直接使用。

int fun1(){
	int *p = new int(3);
}

    也可以不用初始化,然后后面再赋值。

int fun2(){
    int *p = new int;
    *p = 3;
}

    还可以不用指针来接收,而是用一个变量,但需要在new前加上*。

int fun3(){
	int q = *new int;
	q = 3;
	cout << q << endl;
}

    new一个数组时,也需要一个指针来接收首地址。

int* fun4(){
	int *q = new int[3];
	for (int i = 0; i < 3;++i){
		q[i] = i;  //赋值
	}
	return q;
}

    new一个结构体数组也是如此,需要一个结构体指针来接收:

struct student{
	string name;
	int age;
};
student* fun5(){
	student *stu = new student[3]{{ "张三", 20 }, { "李四", 20 }, { "王五", 20 }};
	return stu;
}

Delete

    delete也是个运算符,不需要加头文件,delete用于释放内存。

    new和delete一定要配合使用,如果new了一个新空间后不delete,那么就会造成内存泄漏甚至是程序崩溃。

    而且new和delete也需要匹配使用:

       

     不匹配使用的话也可能会导致内存泄漏和程序崩溃。

void fun1(){
	int *p = new int(3);
	delete p;  //
}

void fun4(){
	int *q = new int[3];
	for (int i = 0; i < 3;++i){
		q[i] = i;  //赋值
	}
	delete[] q;
}

       

### newdelete的基本使用 在C++中,`new``delete`运算符用于动态内存管理。它们不仅负责分配释放内存,还负责调用对象的构造函数析构函数。这与C语言中的`malloc``free`不同,后者仅处理内存分配而不涉及对象的构造析构。 #### 使用`new`进行内存分配 使用`new`分配内存时,可以指定数据类型,并且会自动计算所需内存大小。例如,分配一个整型变量: ```cpp int* p = new int; ``` 对于数组,可以使用如下语法: ```cpp int* arr = new int[10]; ``` 当使用`new`分配内存时,如果内存不足,会抛出`std::bad_alloc`异常。为了避免程序崩溃,可以在分配内存时使用`nothrow`参数: ```cpp int* p = new (std::nothrow) int; ``` #### 使用`delete`进行内存释放 释放由`new`分配的单个对象内存: ```cpp delete p; ``` 释放由`new[]`分配的数组内存: ```cpp delete[] arr; ``` ### newdelete的工作原理 #### `new`操作符 `new`操作符的主要职责是: 1. 调用`operator new`来分配内存。 2. 调用相应的构造函数来初始化对象。 `operator new`是一个全局函数,其默认实现类似于`malloc`,但会抛出异常而不是返回`NULL`。如果内存分配失败,它会调用`new_handler`函数,尝试释放一些内存并再次分配。 ```cpp void* operator new(std::size_t size); ``` #### `delete`操作符 `delete`操作符的主要职责是: 1. 调用相应的析构函数来清理对象。 2. 调用`operator delete`来释放内存。 ```cpp void operator delete(void* ptr); ``` `operator delete`的默认实现类似于`free`,用于释放由`operator new`分配的内存。 ### newdelete的区别 1. **构造与析构**:`new`不仅分配内存,还会调用对象的构造函数;`delete`不仅释放内存,还会调用对象的析构函数。而`malloc``free`仅处理内存分配释放,不涉及构造析构。 2. **异常处理**:`new`在内存不足时会抛出`std::bad_alloc`异常,而`malloc`返回`NULL`。 3. **类型安全**:`new`返回的是具体类型的指针,不需要显式类型转换;`malloc`返回的是`void*`,需要显式类型转换[^1]。 ### newdelete的实现原理 `new``delete`的底层实现依赖于`operator new``operator delete`。`operator new`的默认实现使用`malloc`来分配内存,并在分配失败时抛出异常。`operator delete`的默认实现使用`free`来释放内存[^4]。 对于自定义类型的对象,`new`会在分配的内存上调用构造函数,而`delete`会在释放内存前调用析构函数[^3]。 ### 定位new表达式(Placement-new) 有时需要在已分配的内存中构造对象,这时可以使用定位`new`表达式。例如: ```cpp char buffer[sizeof(MyClass)]; MyClass* obj = new (buffer) MyClass; ``` 此代码在`buffer`中构造了一个`MyClass`对象,而不会分配新的内存[^2]。 ### 内存泄漏 内存泄漏是指程序在运行过程中分配了内存但未能正确释放,导致内存浪费。内存泄漏的危害包括程序性能下降、系统资源耗尽等。为了避免内存泄漏,应确保每次`new`操作都有对应的`delete`操作,并使用智能指针等现代C++特性来管理内存。 ### 相关问题 1. 如何在C++中避免内存泄漏? 2. 什么是定位new表达式?它的应用场景是什么? 3. `operator new``operator delete`可以被重载吗?为什么? 4. `new``malloc`的主要区别是什么? 5. 在什么情况下应该使用`new (nothrow)`? [^1]: 参考站内引用:引用[1] : 参考站内引用:引用[2] [^3]: 参考站内引用:引用[3] [^4]: 参考站内引用:引用[4]
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值