C++ 内存管理

C++ 允许我们在运行时动态地分配内存。这被称为动态内存分配。

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

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

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


C++ new 表达式

我们可以使用 new 表达式在运行时分配内存。例如:

// declare an int pointer
int* point_var;

// dynamically allocate memory
// using the new keyword 
point_var = new int;

// assign value to allocated memory
*point_var = 45;

在这里,我们使用 new 表达式为 int 变量动态分配了内存。

请注意,我们使用了指针 point_var 来动态分配内存。这是因为 new 表达式返回的是内存位置的地址。

我们也可以在同一步骤中分配内存并初始化值:

// dynamically allocate memory
// and assign value
int* point_var = new int{45};

使用此语法可以避免未初始化的指针。未初始化的指针在解引用时可能会导致未定义的行为。因此,这是首选语法。

使用 new 表达式的语法是:

data_type* pointer_variable = new data_type{value};

delete 表达式

一旦我们不再需要使用动态声明的变量,我们就可以释放该变量占用的内存。

为此,我们可以使用 delete 表达式。它将内存返回给操作系统。这被称为内存释放

delete 表达式的语法是:

delete pointer_variable;

让我们看一个例子。

// dynamically allocate memory
// and assign int variable 
int* point_var = new int{45};

// print the value stored in memory
cout << *point_var; // Output: 45

// deallocate the memory
delete point_var;

// set pointer to nullptr
point_var = nullptr;

在这里,我们使用指针 point_varint 变量动态分配了内存。

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

将指针在释放内存后设置为 nullptr 是一个好习惯,以避免在解引用指针时发生未定义的行为。

注意:不正确地释放内存可能导致内存泄漏,进而导致程序消耗大量内存。正确使用 delete 表达式对于防止内存泄漏和确保高效的内存管理至关重要。


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

#include <iostream>
using namespace std;

int main() {

    // dynamically allocate memory
    int* point_int = new int{45};
    float* point_float = new float{45.45f};

    cout << *point_int << endl;
    cout << *point_float << endl;

    // deallocate the memory
    // set pointers to nullptr
    delete point_int;

    delete point_float;
    
    return 0;
}

输出

45
45.45

在此程序中,我们为两个 intfloat 类型的变量动态分配了内存。

在为它们分配值并打印它们之后,我们最终使用 delete 表达式释放了内存。

注意:动态内存分配可以使内存管理更有效率,特别是对于数组,通常我们直到运行时才知道数组的大小。


示例 2:C++ 数组的 new 和 delete 表达式

// C++ program to store GPA of n number of students and display it
// where n is the number of students entered by the user

#include <iostream>
using namespace std;

int main() {

    int num;
    cout << "Enter total number of students: ";
    cin >> num;
    float* ptr;
    
    // memory allocation of num number of floats
    ptr = new float[num];
    
    cout << "Enter GPA of students." << endl;
    for (int i = 0; i < num; ++i) {
    cout << "Student" << i + 1 << ": ";
    cin >> *(ptr + i);
    }
    
    cout << "\nDisplaying GPA of students." << endl;
    for (int i = 0; i < num; ++i) {
    cout << "Student" << i + 1 << ": " << *(ptr + i) << endl;
    }
    
    // ptr memory is released
    delete[] ptr;
    ptr = nullptr;
    
    return 0;
}

输出

Enter total number of students: 4
Enter GPA of students.
Student1: 3.6
Student2: 3.1
Student3: 3.9
Student4: 2.9

Displaying GPA of students.
Student1: 3.6
Student2: 3.1
Student3: 3.9
Student4: 2.9

在此程序中,我们要求用户输入学生数量并将其存储在 num 变量中。

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

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

当我们不再需要该数组时,我们使用以下代码释放了数组内存:

delete[] ptr;.

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


示例 3:C++ 对象的 new 和 delete 表达式

#include <iostream>
using namespace std;

class Student {
    private:
    int age;
    
    public:
    
    // constructor initializes age to 12
    Student() : age(12) {}
    
    void get_age() {
      cout << "Age = " << age << endl;
    }
};

int main() {

    // dynamically declare student object
    Student* ptr = new Student();
    
    // call get_age() function
    ptr->get_age();
    
    // ptr memory is released
    delete ptr;
    
    return 0;
}

输出

Age = 12

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

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

main() 函数中,我们使用 new 表达式创建了一个 Student 对象,并使用指针 ptr 指向其地址。

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

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

ptr->get_age();

请注意箭头运算符 ->。此运算符用于使用指针访问类成员。


为什么要使用动态内存分配?

动态内存分配具有许多优点,例如:

  • 灵活性:动态内存分配允许我们在运行时按需分配内存。当数据结构的大小在编译时未知或在程序执行期间发生变化时,这种灵活性非常有用。
  • 数据结构:链表、树、图和可调整大小的数组(C++ 中的向量)等数据结构通常需要动态分配内存,以适应可变数量的数据。
  • 资源管理:我们可以在需要时分配内存,在不再需要时释放内存。这有助于更好地利用资源。
  • 动态数组:在 C++ 等语言中,静态数组的大小在编译时固定。动态内存分配允许我们创建大小在运行时确定的数组。

阅读更多

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战