Utiliser malloc vs new allocateurs en C++
-
Utiliser le
new
opérateur pour allouer de la mémoire dynamique en C++ -
Utilisez le
new
opérateur etstd::unique_ptr
pour allouer la mémoire dynamique en C++ -
Utilisez la fonction
malloc
etrealloc
/reallocarray
pour allouer la mémoire dynamique
Cet article expliquera plusieurs méthodes d’utilisation de malloc
par rapport aux new
allocateurs en C++.
Utiliser le new
opérateur pour allouer de la mémoire dynamique en C++
new
est l’interface préférée pour gérer directement la mémoire dynamique en C++. Elle construit un objet du type donné et y renvoie le pointeur. Les objets alloués à l’aide de l’opérateur new
sont initialisés par défaut, ce qui signifie que les objets de type intégré et composé ont des valeurs de déchets qui doivent être initialisées avant utilisation.
Notez que new
peut être appelé avec plusieurs notations pour répondre à différents besoins, mais dans l’exemple suivant, nous allouons le tableau int
de taille 10
. Ainsi, le pointeur retourné stocké dans la variable arr1
pointe vers le bloc de mémoire de 40
octets. La fonction initPrintIntVector
n’est implémentée que pour mieux démontrer un exemple pratique de codage. Puisque nous utilisons un pointeur dit nu, il est important de libérer la mémoire allouée avec l’opérateur delete
avant que le programme ne se termine. Cependant, les crochets après l’opérateur delete
sont également nécessaires pour désallouer chaque emplacement dans le tableau.
#include <iomanip>
#include <iostream>
#include <random>
#include <vector>
using std::cout;
using std::endl;
using std::setw;
using std::vector;
constexpr int SIZE = 10;
constexpr int NEW_SIZE = 20;
constexpr int MIN = 1;
constexpr int MAX = 1000;
void initPrintIntVector(int *arr, const int &size) {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_int_distribution<int> distr(MIN, MAX);
for (int i = 0; i < size; ++i) {
arr[i] = distr(eng) % 1000;
cout << setw(2) << arr[i] << "; ";
}
cout << endl;
}
int main() {
int *arr1 = new int[SIZE];
initPrintIntVector(arr1, SIZE);
delete[] arr1;
return EXIT_SUCCESS;
}
Sortie (*aléatoire) :
8; 380; 519; 536; 408; 666; 382; 244; 448; 165;
Utilisez le new
opérateur et std::unique_ptr
pour allouer la mémoire dynamique en C++
Même si le new
opérateur semble être un bon outil pour l’allocation dynamique de la mémoire, il peut être très sujet à des erreurs dans les grandes bases de données avec des manipulations intensives de la mémoire. En effet, l’allocation des ressources mémoire au bon moment est un problème assez difficile à résoudre, et il se traduit le plus souvent par des fuites de mémoire ou des erreurs d’exécution inattendues. C’est pourquoi la bibliothèque standard, depuis la version C++ 11, a ajouté des pointeurs intelligents qui effacent automatiquement la mémoire vers laquelle ils pointent. std::unique_ptr
est un type de pointeurs intelligents, qui se permet seulement de pointer vers l’objet donné. Notez que l’allocation est toujours faite en utilisant le new
opérateur, et après que le pointeur ait été utilisé, nous pouvons quitter le programme sans appeler delete
.
#include <iomanip>
#include <iostream>
#include <random>
#include <vector>
using std::cout;
using std::endl;
using std::setw;
using std::vector;
constexpr int SIZE = 10;
constexpr int NEW_SIZE = 20;
constexpr int MIN = 1;
constexpr int MAX = 1000;
void initPrintIntVector(int *arr, const int &size) {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_int_distribution<int> distr(MIN, MAX);
for (int i = 0; i < size; ++i) {
arr[i] = distr(eng) % 1000;
cout << setw(2) << arr[i] << "; ";
}
cout << endl;
}
int main() {
std::unique_ptr<int[]> arr2(new int[SIZE]);
initPrintIntVector(arr2.get(), SIZE);
return EXIT_SUCCESS;
}
Production :
985; 885; 622; 899; 616; 882; 117; 121; 354; 918;
Utilisez la fonction malloc
et realloc
/reallocarray
pour allouer la mémoire dynamique
D’autre part, le code C++ peut appeler la fonction d’allocation originale de style C - malloc
, ce qui est une manière assez archaïque de manipulation dynamique de la mémoire pour les normes C++ modernes. Ce n’est pas la façon recommandée d’allouer les objets sur le tas, mais du côté positif, malloc
offre une fonctionnalité plus flexible.
malloc
est appelé avec un seul argument qui spécifie la sizeof
de l’objet et renvoie le void*
qui doit être attribué au type correspondant en C++. Le seul avantage de la mémoire allouée à malloc
est qu’elle peut être étendue/réduite par la fonction realloc
ou reallocarray
. La fonction realloc
prend le pointeur vers l’objet et la nouvelle taille comme arguments, alors que reallocarray
prend le pointeur, le nombre d’éléments, et la taille de chaque élément. Notez que si la mémoire de l’objet est étendue, les anciennes valeurs stockées restent intactes, et les éléments nouvellement ajoutés ne sont pas initialisés. Ainsi, l’exemple suivant imprime les éléments arr3
développés uniquement à des fins de démonstration, et cela ne devrait pas être le cas dans le programme du monde réel.
#include <iomanip>
#include <iostream>
#include <random>
#include <vector>
using std::cout;
using std::endl;
using std::setw;
using std::vector;
constexpr int SIZE = 10;
constexpr int NEW_SIZE = 20;
constexpr int MIN = 1;
constexpr int MAX = 1000;
void initPrintIntVector(int *arr, const int &size) {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_int_distribution<int> distr(MIN, MAX);
for (int i = 0; i < size; ++i) {
arr[i] = distr(eng) % 1000;
cout << setw(2) << arr[i] << "; ";
}
cout << endl;
}
void printIntVector(int *arr, const int &size) {
for (int i = 0; i < size; ++i) {
cout << setw(2) << arr[i] << "; ";
}
cout << endl;
}
int main() {
int *arr3 = static_cast<int *>(malloc(SIZE * sizeof(int)));
// int *arr3 = static_cast<int *>(malloc(SIZE * sizeof *arr3));
// int *arr3 = static_cast<int *>(malloc(sizeof(int[SIZE])));
initPrintIntVector(arr3, SIZE);
arr3 = static_cast<int *>(reallocarray(arr3, NEW_SIZE, sizeof(int)));
// arr3 = static_cast<int *>(realloc(arr3, NEW_SIZE * sizeof(int)));
printIntVector(arr3, NEW_SIZE);
free(arr3);
return EXIT_SUCCESS;
}
Production :
128; 346; 823; 134; 523; 487; 370; 584; 730; 268;
128; 346; 823; 134; 523; 487; 370; 584; 730; 268; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook