在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++ 中,推荐使用智能指针来避免手动管理内存。