Bibliothèque de gestion de la mémoire C++<memory>

<memory>Il s'agit d'un fichier d'en-tête de la bibliothèque standard C++ qui contient des modèles et des fonctions pour la gestion dynamique de la mémoire.

En C++, la gestion de la mémoire est un concept important. La gestion dynamique de la mémoire permet aux programmes d'allouer et de libérer de la mémoire à l'exécution, ce qui est très utile lors du traitement de structures de données de taille incertaine. Cependant, une gestion incorrecte de la mémoire peut entraîner des problèmes tels que des fuites de mémoire et des pointeurs suspendus.

<memory>Le fichier d'en-tête fournit des outils tels que des pointeurs intelligents pour aider les développeurs à gérer la mémoire dynamique de manière plus sûre.

Pointeurs intelligents

Les pointeurs intelligents sont<memory>Le contenu principal du fichier d'en-tête. Ce sont des fonctionnalités introduites dans C++11, utilisées pour gérer automatiquement la mémoire allouée dynamiquement. Les principaux types de pointeurs intelligents sont :

  • std::unique_ptr: un pointeur intelligent à propriété exclusive ; à un instant donné, un seulunique_ptrPointe vers une mémoire spécifique.
  • std::shared_ptr: un pointeur intelligent à propriété partagée, plusieursshared_ptrpeuvent pointer vers la même mémoire, et la mémoire est dans le dernier.shared_ptrLibérée lorsqu'elle est détruite.
  • std::weak_ptr: un pointeur intelligent de référence faible, utilisé avecshared_ptrutilisés ensemble, pour éviter les fuites de mémoire causées par des références circulaires.

Exemple

Utilisationstd::unique_ptr

Exemple

#include <iostream>
#include <memory>

class MyClass {
public:
    void doSomething() {
        std::cout << "Doing something" << std::endl;
    }
};

int main() {
    std::unique_ptr<MyClass> myPtr(new MyClass());
    myPtr->doSomething(); // Utiliser un pointeur intelligent pour appeler une fonction membre

    // Lorsque la fonction main se termine, myPtr est détruit, libérant automatiquement la mémoire de l'objet MyClass.
    return 0;
}

Résultat de sortie :

Doing something

Utilisationstd::shared_ptr

Exemple

#include <iostream>
#include <memory>

class MyClass {
public:
    void doSomething() {
        std::cout << "Doing something" << std::endl;
    }
};

int main() {
    std::shared_ptr<MyClass> myPtr1(new MyClass());
    std::shared_ptr<MyClass> myPtr2 = myPtr1;

    myPtr1->doSomething(); // Utilisez myPtr1 pour appeler une fonction membre
    myPtr2->doSomething(); // Utilisez myPtr2 pour appeler une fonction membre

    // Ce n'est que lorsque myPtr1 et myPtr2 sont tous deux détruits que la mémoire de l'objet MyClass sera libérée.
    return 0;
}

Résultat de sortie :

Doing something
Doing something

Utilisationstd::weak_ptr

std::weak_ptrGénéralement pas utilisé seul, mais plutôt avecstd::shared_ptrutilisé en combinaison, pour résoudre le problème de référence circulaire.

Exemple

#include <iostream>
#include <memory>

class Node {
public:
    std::shared_ptr<Node> next;
    std::weak_ptr<Node> prev;

    Node() : next(nullptr), prev() {}
};

int main() {
    std::shared_ptr<Node> node1 = std::make_shared<Nœud>();
    std::shared_ptr<Node> node2 = std::make_shared<Nœud>();

    node1->next = node2;
    node2->prev = node1;

    // Référence circulaire, mais l'utilisation de weak_ptr évite une fuite de mémoire.
    return 0;
}

Dans cet exemple,node1etnode2crée une référence circulaire. PuisqueprevOuiweak_ptr, quandnode1etnode2deshared_ptrLorsqu'ils sont détruits, la mémoire vers laquelle ils pointent est également correctement libérée.

Allocateur

Les allocateurs sont une autre partie importante de <memory>.

Les allocateurs sont utilisés pour allouer de la mémoire aux conteneurs ; tous les conteneurs de la bibliothèque standard utilisent des allocateurs pour gérer l'allocation de mémoire.

std::allocator

std::allocator est l'allocateur standard, fournissant des fonctions de base d'allocation et de désallocation de mémoire.

Exemple

#include <memory>
#include <vector>

int main() {
    std::allocator<int> alloc;
    int* p = alloc.allocate(1); // Allouer de la mémoire
    alloc.construct(p, 42); // Construire l'objet

    std::cout << *p << std::endl;

    alloc.destroy(p); // Détruire l'objet
    alloc.deallocate(p, 1); // libérer la mémoire

    return 0;
}

Autres outils de gestion de la mémoire

std::align

std::align est utilisé pour ajuster l'alignement des pointeurs afin de garantir que la mémoire allouée satisfait à des exigences d'alignement spécifiques.

Exemple

#include <memory>
#include <iostream>

int main() {
    alignas(16) char buffer[64];
    void* p = buffer;
    size_t space = sizeof(buffer);

    void* aligned_ptr = std::align(16, sizeof(int), p, space);
    if (aligned_ptr) {
        std::cout << "Mémoire alignée"\n";
    } else {
        std::cout << "Échec de l'alignement mémoire"\n";
    }

    return 0;
}

<memory>Le fichier d'en-tête est une partie importante de la bibliothèque standard C++ pour la gestion dynamique de la mémoire.

En utilisant des pointeurs intelligents, tels queunique_ptr、shared_ptretweak_ptr, les développeurs peuvent gérer la mémoire de manière plus sûre et plus efficace, en évitant les erreurs courantes de gestion de mémoire. J'espère que cet article aidera les débutants à mieux comprendre et utiliser C++<memory>Fichier d'en-tête.

autres extensions