跳到主要内容

C++ 内存管理:new 和 delete

提示
  1. 动态内存分配:在C++中,可以使用new操作符在运行时为变量或数组分配内存,这称为动态内存分配。与Java和Python等语言不同,C++需要手动释放动态分配的内存。
  2. new操作符new操作符用于为变量分配内存,返回内存地址。例如,使用int* pointVar = new int;为整型变量分配内存。对于数组,new返回数组的第一个元素的地址。
  3. delete操作符:当动态分配的变量不再需要时,使用delete操作符释放内存。对于数组,使用delete[]释放内存。例如,delete pointVar;delete[] ptr;分别用于释放单个变量和数组所占用的内存。

C++允许我们在运行时为变量或数组分配内存。这被称为动态内存分配。

在其他编程语言如Java和Python中,编译器会自动管理分配给变量的内存。但在C++中情况并非如此。

在C++中,我们需要在不再使用变量后手动释放动态分配的内存。

我们可以分别使用newdelete运算符来动态地分配和释放内存。

C++ new 操作符

new 操作符用于为变量分配内存。例如,

// 声明一个 int 指针
int* pointVar;

// 使用 new 关键字动态分配内存
pointVar = new int;

// 给分配的内存赋值
*pointVar = 45;

这里,我们使用 new 操作符为一个 int 变量动态分配了内存。注意我们使用指针 pointVar 来动态分配内存。这是因为 new 操作符返回内存位置的地址。

对于数组,new 操作符返回数组第一个元素的地址。

从上面的例子中可以看出,使用 new 操作符的语法是:

pointerVariable = new dataType;

delete 操作符

一旦我们不再需要动态声明的变量,我们可以释放该变量占用的内存。为此,使用 delete 操作符。它将内存返回给操作系统。这被称为内存释放

此操作符的语法是:

delete pointerVariable;

考虑以下代码:

// 声明一个 int 指针
int* pointVar;

// 动态分配一个 int 变量的内存
pointVar = new int;

// 为变量内存赋值
*pointVar = 45;

// 输出存储在内存中的值
cout << *pointVar; // 输出:45

// 释放内存
delete pointVar;

这里,我们使用指针 pointVar 为一个 int 变量动态分配了内存。

打印 pointVar 的内容后,我们使用 delete 释放了内存。

注意:如果程序使用 new 使用大量不必要的内存,系统可能会因为没有可用的内存而崩溃。在这种情况下,delete 操作符可以帮助系统避免崩溃。

示例 1:C++ 动态内存分配

#include <iostream>
using namespace std;

int main() {

// 声明一个 int 指针
int* pointInt;

// 声明一个 float 指针
float* pointFloat;

// 动态分配内存
pointInt = new int;
pointFloat = new float;

// 赋值
*pointInt = 45;
*pointFloat = 45.45f;

cout << *pointInt << endl;
cout << *pointFloat << endl;

// 释放内存
delete pointInt;
delete pointFloat;

return 0;
}

输出

45
45.45

在这个程序中,我们为 intfloat 类型的两个变量动态分配了内存。在为它们赋值并打印它们之后,我们最终使用以下代码释放了内存:

delete pointInt;
delete pointFloat;

注意:动态内存分配可以使内存管理更加高效。

特别是对于数组,我们很多时候直到运行时才知道数组的大小。

示例 2:C++ new 和 delete 操作符用于数组

// C++ 程序,存储 n 个学生的 GPA 并显示
// 其中 n 是用户输入的学生数量

#include <iostream>
using namespace std;

int main() {

int num;
cout << "输入学生总数: ";
cin >> num;
float* ptr;

// 为 num 个 float 分配内存
ptr = new float[num];

cout << "输入学生的 GPA." << endl;
for (int i = 0; i < num; ++i) {
cout << "学生" << i + 1 << ": ";
cin >> *(ptr + i);
}

cout << "\n显示学生的 GPA." << endl;
for (int i = 0; i < num; ++i) {
cout << "学生" << i + 1 << ": " << *(ptr + i) << endl;
}

// 释放 ptr 占用的内存
delete[] ptr;

return 0;
}

输出

输入学生总数: 4
输入学生的 GPA.
学生1: 3.6
学生2: 3.1
学生3: 3.9
学生4: 2.9

显示学生的 GPA.
学生1: 3.6
学生2: 3.1
学生3: 3.9
学生4: 2.9

在这个程序中,我们向用户询问学生数量,并将其存储在 num 变量中。

然后,我们使用 new 为 float 数组动态分配了内存。

我们使用指针表示法输入数组的数据(稍后打印它们)。

当我们不再需要数组时,我们使用代码 delete[] ptr; 释放数组内存。

注意 delete 后面的 []。我们使用方括号 [] 表示内存释放是针对数组的。

示例 3:C++ new 和 delete 操作符用于对象

#include <iostream>
using namespace std;

class Student {
private:
int age;

public:

// 构造函数将 age 初始化为 12
Student() : age(12) {}

void getAge() {
cout << "年龄 = " << age << endl;
}
};

int main() {

// 动态声明 Student 对象
Student* ptr = new Student();

// 调用 getAge() 函数
ptr->getAge();

// 释放 ptr 占用的内存
delete ptr;

return 0;
}

输出

年龄 = 12

在这个程序中,我们创建了一个 Student 类,该类有一个私有变量 age。

我们在默认构造函数 Student() 中将 age 初始化为 12 并通过函数 getAge() 打印其值。

main() 中,我们使用 new 操作符创建了一个 Student 对象,并使用指针 ptr 指向其地址。

对象创建时,Student() 构造函数会将 age 初始化为 12

然后,我们使用以下代码调用 getAge() 函数:

ptr->getAge();

注意箭头操作符 ->。该操作符用于使用指针访问类成员。