C++ 动态内存

C++ 动态内存

理解C++中动态内存的工作原理对于成为一名优秀的C++程序员至关重要。你的C++程序的内存被分为两部分−

  • 堆栈 − 函数内部声明的所有变量将占用堆栈中的内存。

  • − 这是程序中未使用的内存,当程序运行时可以用于动态分配内存。

很多时候,你事先不知道需要多少内存来存储特定信息在定义的变量中,所需内存的大小可以在运行时确定。

你可以在堆中为给定类型的变量在运行时分配内存,使用C++中的特殊运算符,该运算符返回分配空间的地址。这个运算符被称为 new 运算符。

如果你不再需要动态分配的内存,你可以使用 delete 运算符,它会释放之前由new运算符分配的内存。

new和delete运算符

以下是通用语法,用于使用 new 运算符为任何数据类型动态分配内存。

new data-type;

在这里, data-type 可以是任何内置的数据类型,包括数组或任何用户定义的数据类型,包括类或结构体。让我们从内置的数据类型开始。例如,我们可以定义一个指向double类型的指针,然后在执行时请求分配内存。我们可以使用 new 操作符和以下语句来实现这一点:

double* pvalue  = NULL; // Pointer initialized with null
pvalue  = new double;   // Request memory for the variable

如果使用的自由存储空间已经耗尽,那么可能无法成功分配内存。因此,良好的做法是检查new运算符是否返回空指针,并采取相应的措施,如下所示−

double* pvalue  = NULL;
if( !(pvalue  = new double )) {
   cout << "Error: out of memory." <<endl;
   exit(1);
}

C中的 malloc() 函数在C++中仍然存在,但建议避免使用malloc()函数。new的主要优势是,它不仅分配内存,还构造对象,这是C++的主要目的。

在任何时候,当您感觉不再需要动态分配的变量时,您可以使用’ delete ‘运算符释放占据free store中的内存,如下所示−

delete pvalue;        // Release memory pointed to by pvalue

让我们将上述概念放在一起,形成以下示例,以展示’new’和’delete’是如何工作的 –

#include <iostream>
using namespace std;

int main () {
   double* pvalue  = NULL; // Pointer initialized with null
   pvalue  = new double;   // Request memory for the variable

   *pvalue = 29494.99;     // Store value at allocated address
   cout << "Value of pvalue : " << *pvalue << endl;

   delete pvalue;         // free up the memory.

   return 0;
}

如果我们编译并运行上面的代码,将会产生以下结果 –

Value of pvalue : 29495

动态内存分配给数组

考虑你想要为一个字符数组分配内存,即包含20个字符的字符串。使用与上面相同的语法,我们可以动态地分配内存,如下所示。

char* pvalue  = NULL;         // Pointer initialized with null
pvalue  = new char[20];       // Request memory for the variable

将刚刚创建的数组移除的语句如下所示 –

delete [] pvalue;             // Delete array pointed to by pvalue

按照与new操作符相似的通用语法,您可以按照以下方式分配多维数组:

double** pvalue  = NULL;      // Pointer initialized with null 
pvalue  = new double [3][4];  // Allocate memory for a 3x4 array

然而,释放多维数组的内存的语法仍然与上述相同 –

delete [] pvalue;            // Delete array pointed to by pvalue

为对象动态分配内存

对象与简单数据类型没有区别。例如,考虑以下代码,我们将使用对象数组来说明概念 –

#include <iostream>
using namespace std;

class Box {
   public:
      Box() { 
         cout << "Constructor called!" <<endl; 
      }
      ~Box() { 
         cout << "Destructor called!" <<endl; 
      }
};
int main() {
   Box* myBoxArray = new Box[4];
   delete [] myBoxArray; // Delete array

   return 0;
}

如果您要分配一个包含四个Box对象的数组,那么Simple构造函数将被调用四次,而在删除这些对象时,析构函数也将被调用相同次数。

如果我们编译并运行上面的代码,将会产生以下结果−

Constructor called!
Constructor called!
Constructor called!
Constructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程