C++ DEVELOPER SITE
PYTHONPHP7JAVA
 

C++ dynamic memory


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

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

A lot of times, you can't predict in advance how much memory is needed to store specific information in a defined variable. The amount of memory required needs to be determined at runtime.

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

If you no longer need dynamically allocated memory space, you can use the delete operator to remove memory previously allocated by the new operator.

new and delete operators

The following is a general 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 user-defined data type, including classes or structures. Let's first look at the built-in data types. For example, we can define a pointer to a 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; // Initialize to null Pointer pvalue = new double; // Request memory for a variable

If the free storage area has been used up, it may not be possible to allocate memory successfully. So it is recommended to check if the new operator returns a NULL pointer and take the appropriate action:

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

malloc() function appears in C and still exists in C, but it is recommended not to use the malloc() function. 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 is no longer needed, you can use the delete operator to free up the memory it occupies, as follows:

delete pvalue; // Release the memory pointed to by pvalue

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

Example

#include <iostream> using namespace std; int main () { double* pvalue = NULL; // pointer initialized to null< Span class="hl-code"> pvalue= new< Span class="hl-code"> double; // Request memory for variables *pvalue= 29494 .99; // Store values at assigned addresses cout << "Value of pvalue : " << *pvalue << endl; delete pvalue; // Free memory return 0; }

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

Value of pvalue : 29495

Dynamic memory allocation for arrays

Assuming we want to allocate memory for a character array (a string of 20 characters), we can use the syntax in the above example to dynamically allocate memory for the array as follows:

char* pvalue  = NULL;   // Initialized to null pointer
Pvalue = new char[20]; // request memory for variables

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

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

The following is a general syntax for the new operator that allocates memory for multidimensional arrays as follows:

One-dimensional array

//Dynamic allocation, array length is m int *array=new int [m]//Free memory delete [] array;

Two-dimensional array

int **array // Assume that the first dimension of the array is m, and the second dimension is n // Dynamically allocate space array = new int *[m]; for( int i=0; i<m; i++ ) { array[i] = new int [n] ; } //freed for( int i=0; i<m; i++ ) { delete [] arrary[i]; } delete [] array;

Two-dimensional array Example test:

Example

#include <iostream> using namespace std; int main() { int **p; int i,j; //p[4][8] //Start to assign 2 rows and 8 columns of 2D data p = new int *[4]; for(i=0;i<4;i++){ p[i]=new int [8]; } for(i=0; i<4; i++){ for(j=0; j<8; j++){ p[i][j] = j*i; } } //Print data for(i=0; i<4; i++){ for(j=0; j<8; j++) { if(j==0) cout<<endl; cout<<p[i][j]<<"\t"; } } //Start releasing the requested heap for(i=0; i<4; i++){ delete [] p[i]; } delete [] p; return 0; }

3D array

int ***array; // Suppose the first dimension of the array is m, the second dimension is n, and the third dimension is h // Dynamically allocate space array = new int **[m]; for( int i=0; i<m; i++ ) { array[i] = new int *[n]; for( int j=0; j<n; j++ ) { array[i][j] = new int [h]; } } //freed for( int i=0; i<m; i++ ) { for( int j=0; j<n; j++ ) { delete[] array[i][j]; } delete[] array[i]; } delete[] array;

3D array test example:

Example

#include <iostream> using namespace std; int main() { int i,j,k; // p[2][3][4] int ***p; p = new int **[2]; for(i=0; i<2; i++) { p[i]=new int *[3]; for(j=0; j<3; j++) p[i][j]=new int[4]; } //Output p[i][j][k] 3D data for(i=0; i<2; i++) { for(j=0; j<3; j++) { for(k=0;k<4;k++) { p[i][j][k]=i+j+k; cout<<p[i][j][k]<<" "; } cout<<endl; } cout<<endl; } // Free memory for(i=0; i<2; i++) { for(j=0; j<3; j++) { delete [] p[i][j]; } } for(i=0; i<2; i++) { delete [] p[i]; } delete [] p; return 0; }

Dynamic memory allocation for objects

Objects are no different than simple data types. For example, look at the code below, we will use an array of objects to clarify this concept:

Example

#include <iostream> using namespace std; class Box { public: Box() { cout << "Call constructor!" <<endl; } ~Box() { cout << "Call destructor!" <<endl; } }; int main( ) { Box* myBoxArray = new Box[4]; delete [] myBoxArray; // Delete array return 0; }

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

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

Call the constructor! 
Call the constructor! 
Call the constructor! 
Call the constructor! 
Call the destructor! 
Call the destructor! 
Call the destructor! 
Call the destructor!