Cplusplus 简明教程
C++ Dynamic Memory
真正理解动态内存如何在 C 中工作对于成为一名优秀的 C 程序员至关重要。C++ 程序中的内存分为两个部分 -
A good understanding of how dynamic memory really works in C is essential to becoming a good C programmer. Memory in your C++ program is divided into two parts −
-
The stack − All variables declared inside the function will take up memory from the stack.
-
The heap − This is unused memory of the program and can be used to allocate the memory dynamically when program runs.
很多时候,您事先不知道在已定义变量中存储特定信息需要多少内存,并且所需内存的大小可以在运行时确定。
Many times, you are not aware in advance how much memory you will need to store particular information in a defined variable and the size of required memory can be determined at run time.
您可以在堆中为给定类型的变量在运行时分配内存,方法是在 C++ 中使用一个特殊的运算符,该运算符返回已分配空间的地址。此运算符称为 new 运算符。
You can allocate memory at run time within the heap for the variable of a given type using a special operator in C++ which returns the address of the space allocated. This operator is called new operator.
如果你不再需要动态分配的内存,你可以使用 delete 运算符,它可以取消分配那些之前通过 new 运算符分配的内存。
If you are not in need of dynamically allocated memory anymore, you can use delete operator, which de-allocates memory that was previously allocated by new operator.
new and delete Operators
存在以下通用的语法来使用 new 运算符,以动态地为任何数据类型分配内存。
There is following generic syntax to use new operator to allocate memory dynamically for any data-type.
new data-type;
此处, data-type 可以是任何内置数据类型,包括数组或任何用户自定义数据类型,包括类或结构。让我们从内置数据类型开始。例如,我们可以定义一个指向 double 类型的指针,然后要求在执行期间分配内存。我们可以使用 *new * 运算符和以下语句来执行此操作:
Here, data-type could be any built-in data type including an array or any user defined data types include class or structure. Let us start with built-in data types. For example we can define a pointer to type double and then request that the memory be allocated at execution time. We can do this using the *new * operator with the following statements −
double* pvalue = NULL; // Pointer initialized with null
pvalue = new double; // Request memory for the variable
如果 free store 已用完,则可能无法成功分配内存。因此,最好检查 new 运算符是否返回 NULL 指针并采取如下适当措施:
The memory may not have been allocated successfully, if the free store had been used up. So it is good practice to check if new operator is returning NULL pointer and take appropriate action as below −
double* pvalue = NULL;
if( !(pvalue = new double )) {
cout << "Error: out of memory." <<endl;
exit(1);
}
C 的 malloc() 函数在 C 中仍然存在,但建议避免使用 malloc() 函数。new 比 malloc() 的主要优势在于,new 不仅分配内存,它还构造对象,这是 C 的主要目的。
The malloc() function from C, still exists in C, but it is recommended to avoid using malloc() function. The main advantage of new over malloc() is that new doesn’t just allocate memory, it constructs objects which is prime purpose of C.
当您觉得动态分配的变量不再需要时,您可以使用 delete
运算符释放其在 free store 中占据的内存,如下所示:
At any point, when you feel a variable that has been dynamically allocated is not anymore required, you can free up the memory that it occupies in the free store with the ‘delete’ operator as follows −
delete pvalue; // Release memory pointed to by pvalue
让我们使用以上概念并形成以下示例,以展示 new
和 delete
如何工作:
Let us put above concepts and form the following example to show how ‘new’ and ‘delete’ work −
#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;
}
如果我们编译并运行上述代码,这将产生以下结果:
If we compile and run above code, this would produce the following result −
Value of pvalue : 29495
Dynamic Memory Allocation for Arrays
假定您想为一个字符数组(即 20 个字符的字符串)分配内存。使用我们上面使用的相同语法,我们可以按如下所示动态分配内存。
Consider you want to allocate memory for an array of characters, i.e., string of 20 characters. Using the same syntax what we have used above we can allocate memory dynamically as shown below.
char* pvalue = NULL; // Pointer initialized with null
pvalue = new char[20]; // Request memory for the variable
要移除我们刚刚创建的数组,语句将如下所示:
To remove the array that we have just created the statement would look like this −
delete [] pvalue; // Delete array pointed to by pvalue
按照 new 运算符的类似通用语法,您可以为多维数组分配内存,如下所示:
Following the similar generic syntax of new operator, you can allocate for a multi-dimensional array as follows −
double** pvalue = NULL; // Pointer initialized with null
pvalue = new double [3][4]; // Allocate memory for a 3x4 array
然而,释放多维数组内存的语法仍与上面相同:
However, the syntax to release the memory for multi-dimensional array will still remain same as above −
delete [] pvalue; // Delete array pointed to by pvalue
Dynamic Memory Allocation for Objects
对象与简单数据类型没有什么区别。例如,考虑以下代码,我们将在其中使用一个对象数组来阐明这个概念:
Objects are no different from simple data types. For example, consider the following code where we are going to use an array of objects to clarify the concept −
#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 构造函数将被调用四次,在删除这些对象时,析构函数也将被调用相同次数。
If you were to allocate an array of four Box objects, the Simple constructor would be called four times and similarly while deleting these objects, destructor will also be called same number of times.
如果我们编译并运行上述代码,这将产生以下结果:
If we compile and run above code, this would produce the following result −
Constructor called!
Constructor called!
Constructor called!
Constructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!