在C++中,动态内存管理是通过运算符 new
、new[]
、delete
和 delete[]
来实现的。它们分别用于分配和释放动态内存。
1. new
和 new[]
new
1.用途:用于分配单个对象的内存。
2.语法:
cpp
Type* ptr = new Type;
行为:
1.分配足够的内存来存储一个 Type 类型的对象。
2.调用 Type 的构造函数来初始化对象。
3.返回指向分配内存的指针。
示例:
cpp
int* ptr = new int; // 分配一个 int 类型的内存
*ptr = 10; // 初始化
new[]
1.用途:用于分配数组的内存。
2.语法:
cpp
Type* ptr = new Type[size];
行为:
1.分配足够的内存来存储 size 个 Type 类型的对象。
2.对数组中的每个元素调用 Type 的构造函数。
3.返回指向数组第一个元素的指针。
示例:
cpp
int* arr = new int[5]; // 分配一个包含 5 个 int 的数组
for (int i = 0; i < 5; ++i) {
arr[i] = i + 1; // 初始化数组
}
2. delete
和 delete[]
delete
1.用途 :用于释放通过 new
分配的单个对象的内存。
2.语法:
cpp
delete ptr;
行为:
1.调用 ptr 指向对象的析构函数。
2.释放对象占用的内存。
示例:
cpp
int* ptr = new int;
*ptr = 10;
delete ptr; // 释放内存
delete[]
1.用途 :用于释放通过 new[]
分配的数组的内存。
2.语法:
cpp
delete[] ptr;
行为:
1.对数组中的每个元素调用析构函数。
2.释放整个数组占用的内存。
示例:
cpp
int* arr = new int[5];
delete[] arr; // 释放数组内存
3. 比较与对比
特性 | new |
new[] |
delete |
delete[] |
---|---|---|---|---|
用途 | 分配单个对象的内存 | 分配数组的内存 | 释放单个对象的内存 | 释放数组的内存 |
语法 | Type* ptr = new Type; |
Type* ptr = new Type[size]; |
delete ptr; |
delete[] ptr; |
构造函数调用 | 调用单个对象的构造函数 | 调用数组中每个元素的构造函数 | 调用单个对象的析构函数 | 调用数组中每个元素的析构函数 |
析构函数调用 | 不直接涉及 | 不直接涉及 | 调用单个对象的析构函数 | 调用数组中每个元素的析构函数 |
内存释放范围 | 单个对象 | 整个数组 | 单个对象 | 整个数组 |
错误使用后果 | 使用 delete[] 会导致未定义行为 |
使用 delete 会导致未定义行为 |
使用 delete[] 会导致未定义行为 |
使用 delete 会导致未定义行为 |
4. 注意事项
-
配对使用:
-
new
必须与delete
配对使用。 -
new[]
必须与delete[]
配对使用。 -
如果混用(例如用
delete
释放new[]
分配的内存),会导致未定义行为(如内存泄漏或程序崩溃)。
-
-
内存泄漏:
- 如果忘记调用
delete
或delete[]
,会导致内存泄漏。
- 如果忘记调用
-
初始化:
-
new
和new[]
会调用构造函数,因此分配的内存会被初始化。 -
如果需要避免初始化,可以使用
std::malloc
或std::calloc
(但不推荐,因为它们不会调用构造函数)。
-
-
异常安全:
- 如果
new
或new[]
分配内存失败,会抛出std::bad_alloc
异常(除非使用nothrow
版本)。
- 如果
-
智能指针:
- 在现代 C++ 中,推荐使用智能指针(如
std::unique_ptr
和std::shared_ptr
)来管理动态内存,避免手动调用delete
或delete[]
。
- 在现代 C++ 中,推荐使用智能指针(如
5. 示例代码
cpp
#include <iostream>
class MyClass {
public:
MyClass() { std::cout << "Constructor called!\n"; }
~MyClass() { std::cout << "Destructor called!\n"; }
};
int main() {
// 使用 new 和 delete
MyClass* obj = new MyClass; // 调用构造函数
delete obj; // 调用析构函数
// 使用 new[] 和 delete[]
MyClass* arr = new MyClass[3]; // 调用 3 次构造函数
delete[] arr; // 调用 3 次析构函数
return 0;
}
6. 总结
1.new
和 new[]
用于动态分配内存,分别用于单个对象和数组。
2.delete
和 delete[]
用于释放内存,必须与 new
和 new[]
配对使用。
3.混用 new
/delete
和 new[]
/delete[]
会导致未定义行为。
4.在现代 C++ 中,推荐使用智能指针来避免手动管理内存。