Mémoire dynamique C++
Comprendre le fonctionnement de la mémoire dynamique en C++ est essentiel pour devenir un programmeur C++ compétent. La mémoire dans un programme C++ est divisée en deux parties :
Pile : Toutes les variables déclarées à l'intérieur de la fonction occuperont la mémoire de la pile.
Tas : Il s'agit de la mémoire inutilisée dans le programme et peut être utilisée pour allouer dynamiquement de la mémoire pendant l'exécution du programme.
Souvent, vous ne pouvez pas prédire à l'avance la quantité de mémoire nécessaire pour stocker des informations spécifiques dans une variable définie. La taille de la mémoire requise doit être déterminée au moment de l'exécution.
En C++, vous pouvez allouer de la mémoire sur le tas au moment de l'exécution pour une variable d'un type donné à l'aide d'opérateurs spéciaux, qui renvoient l'adresse de l'espace alloué. Cet opérateur est le nouvel opérateur.
Si vous n'avez pas besoin d'allouer dynamiquement de la mémoire, vous pouvez utiliser l'opérateur delete pour supprimer la mémoire précédemment allouée par le nouvel opérateur.
opérateurs new et delete
Ce qui suit est la syntaxe générale pour utiliser l'opérateur new pour allouer dynamiquement de la mémoire pour tout type de données :
new data-type;
Ici, data - type peut être n'importe quel type de données intégré, y compris des tableaux, ou tout type de données défini par l'utilisateur, y compris des classes ou des structures. Examinons d'abord les types de données intégrés. Par exemple, nous pourrions définir un pointeur pour taper double, puis demander de la mémoire, qui est allouée au moment de l'exécution. Nous pouvons accomplir cela en utilisant l'opérateur new comme suit :
double* pvalue = NULL; // 初始化为 null 的指针 pvalue = new double; // 为变量请求内存
Si la zone de stockage libre a été épuisée, l'allocation de mémoire peut échouer. Par conséquent, il est recommandé de vérifier si l'opérateur new renvoie un pointeur NULL et d'effectuer les actions appropriées suivantes :
double* pvalue = NULL; if( !(pvalue = new double )) { cout << "Error: out of memory." <<endl; exit(1); }
malloc() La fonction est apparue en langage C et existe toujours en C++ , mais il est recommandé de ne pas utiliser autant que possible la fonction malloc(). Le principal avantage de new par rapport à la fonction malloc() est que new non seulement alloue de la mémoire, mais crée également des objets.
A tout moment, lorsque vous estimez qu'une variable à laquelle on a alloué dynamiquement de la mémoire n'est plus nécessaire, vous pouvez utiliser l'opérateur delete pour libérer la mémoire qu'elle occupe, comme suit :
delete pvalue; // 释放 pvalue 所指向的内存
Les concepts ci-dessus sont utilisés dans l'exemple suivant, qui montre comment utiliser les opérateurs new et delete :
#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; }
Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :
Value of pvalue : 29495
Allocation dynamique de mémoire pour les tableaux
Supposons que nous souhaitions allouer de la mémoire pour un tableau de caractères (une chaîne de 20 caractères), nous pouvons utiliser la syntaxe de l'exemple ci-dessus pour allouer dynamiquement de la mémoire pour le tableau, comme suit Afficher :
char* pvalue = NULL; // 初始化为 null 的指针 pvalue = new char[20]; // 为变量请求内存
Pour supprimer le tableau que nous venons de créer, l'instruction est la suivante :
delete [] pvalue; // 删除 pvalue 所指向的数组
Ce qui suit est la syntaxe générale de l'opérateur new, qui peut allouer de la mémoire pour les tableaux multidimensionnels, comme suit :
int ROW = 2; int COL = 3; double **pvalue = new double* [ROW]; // 为行分配内存 // 为列分配内存 for(int i = 0; i < COL; i++) { pvalue[i] = new double[COL]; }
Libérer la mémoire du tableau multidimensionnel :
for(int i = 0; i < COL; i++) { delete[] pvalue[i]; } delete [] pvalue;
Allocation dynamique de mémoire des objets
Les objets ne sont pas différents des types de données simples. Par exemple, jetez un œil au code suivant, où nous utiliserons un tableau d'objets pour clarifier ce 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; }
Si vous souhaitez allouer de la mémoire pour un tableau contenant quatre objets Box, le constructeur sera appelé 4 fois, de même lorsque les objets seront supprimés, le destructeur sera également appelé le même nombre de fois (4 fois).
Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :
调用构造函数! 调用构造函数! 调用构造函数! 调用构造函数! 调用析构函数! 调用析构函数! 调用析构函数! 调用析构函数!