Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Dynamic memory in C+


May 11, 2021 C++


Table of contents


The dynamic memory of the C+

Understanding how dynamic memory works in C+ is essential to being a qualified C++ programmer. The memory in the C++ program is divided into two parts:

  • Stack: All variables declared inside the function will consume stack memory.
  • Heap: This is unused memory in the program and can be used to dynamically allocate memory while the program is running.

Many times, you can't predict in advance how much memory is needed to store specific information in a defined variable, and the size of the memory required needs needs to be determined at runtime.

In C+, you can use special operators to allocate memory in the heap at runtime for a given type of variable, which returns the allocated spatial address. This operator is the new operator.

If you do not need to allocate memory dynamically, you can use the delete operator to delete the memory previously allocated by the new operator.

The new and delete operators

Here is a common syntax for using the new operator to dynamically allocate memory for any data type:

new data-type;

Here, data-type can be any built-in data type, including arrays, or any data type customized by a user, including a class or structure. L et's first look at the built-in data types. F or example, we can define a pointer to the double type and then request memory, which is allocated at execution time. We can do this by using the new operator as follows:

double* pvalue  = NULL; // 初始化为 null 的指针
pvalue  = new double;   // 为变量请求内存

If the free store is used up, memory may not be allocated successfully. Therefore, it is recommended to check whether the new operator returns a NULL pointer and take the following appropriate action:

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

}

The malloc() function appears in the C language and still exists in C, but it is recommended that you avoid using the malloc() function as much as possible. The main advantage of new compared to the malloc() function is that new not only allocates memory, it also creates objects.

At any time, when you feel that a variable that has been dynamically allocated memory no longer needs to be used, you can use the delete operator to free up the memory it occupies, as follows:

delete pvalue;        // 释放 pvalue 所指向的内存

The following example uses the above concept to demonstrate how to use the new and delete operators:

#include <iostream>
using namespace std;

int main ()
{
   double* pvalue  = NULL; // 初始化为 null 的指针
   pvalue  = new double;   // 为变量请求内存
 
   *pvalue = 29494.99;     // 在分配的地址存储值
   cout << "Value of pvalue : " << *pvalue << endl;

   delete pvalue;         // 释放内存

   return 0;
}

When the above code is compiled and executed, it produces the following results:

Value of pvalue : 29495

Dynamic memory allocation for the array

Suppose we want to allocate memory for an array of characters (a string of 20 characters), and we can use the syntax in the instance above to dynamically allocate memory for the array, as follows:

char* pvalue  = NULL;   // 初始化为 null 的指针
pvalue  = new char[20]; // 为变量请求内存

To delete the array we just created, the statement is as follows:

delete [] pvalue;        // 删除 pvalue 所指向的数组

Here is the general syntax of the new operator, which allocates memory for multi-dimensional arrays, as follows:

int ROW = 2;
int COL = 3;
double **pvalue  = new double* [ROW]; // 为行分配内存

// 为列分配内存
for(int i = 0; i < COL; i++) {
    pvalue[i] = new double[COL];
}

Free up multi-dimensional array memory:

for(int i = 0; i < COL; i++) {
    delete[] pvalue[i];
}
delete [] pvalue; 

The dynamic memory allocation of the object

Objects are no different from simple data types. For example, look at the following code, and we'll use an array of objects to figure out the concept:

#include <iostream>
using namespace std;

class Box
{
   public:
      Box() { 
         cout << "调用构造函数!" <<endl; 
      }
      ~Box() { 
         cout << "调用析构函数!" <<endl; 
      }
};

int main( )
{
   Box* myBoxArray = new Box[4];

   delete [] myBoxArray; // Delete array

   return 0;
}

If you want to allocate memory to an array of four Box objects, the constructor will be called four times, and the destructor will be called the same number of times (4 times) when these objects are deleted.

When the above code is compiled and executed, it produces the following results:

调用构造函数!
调用构造函数!
调用构造函数!
调用构造函数!
调用析构函数!
调用析构函数!
调用析构函数!
调用析构函数!