Maison > développement back-end > C++ > L'utilisation du placement nouveau sur les tableaux C est-elle portable ?

L'utilisation du placement nouveau sur les tableaux C est-elle portable ?

DDD
Libérer: 2024-11-18 05:38:02
original
706 Les gens l'ont consulté

Is Using Placement New on C   Arrays Portable?

Placement portable nouveau pour les tableaux

L'opérateur de placement new de la bibliothèque standard permet l'allocation de mémoire à une adresse spécifiée. Cependant, son utilisation avec des tableaux soulève des problèmes de portabilité en raison de divergences potentielles entre le pointeur renvoyé et l'adresse transmise.

Comprendre le problème

Lors de l'utilisation du placement new pour tableaux, le pointeur renvoyé peut ne pas s’aligner sur l’adresse fournie. Ceci est expliqué dans la note 12 du 5.3.4 de la norme C. Par conséquent, l'allocation d'un tampon spécifiquement pour le tableau devient problématique.

Considérez l'exemple suivant :

#include <iostream>
#include <new>

class A {
public:
    A() : data(0) {}
    ~A() {}
    int data;
};

int main() {
    const int NUMELEMENTS = 20;

    char *pBuffer = new char[NUMELEMENTS * sizeof(A)];
    A *pA = new(pBuffer) A[NUMELEMENTS];

    // Output may show pA as four bytes higher than pBuffer
    std::cout << "Buffer address: " << pBuffer << ", Array address: " << pA << std::endl;

    delete[] pBuffer;

    return 0;
}
Copier après la connexion

Cet exemple entraîne souvent une corruption de la mémoire sous Microsoft Visual Studio. L'examen de la mémoire révèle que le compilateur préfixe l'allocation du tableau avec quatre octets, stockant probablement le nombre d'éléments du tableau. Ce comportement varie en fonction du compilateur et de la classe utilisée.

Solution portable

Pour résoudre ce problème de portabilité, évitez d'utiliser le placement new directement sur les tableaux. Au lieu de cela, envisagez d'allouer chaque élément du tableau individuellement à l'aide du placement new :

#include <iostream>
#include <new>

class A {
public:
    A() : data(0) {}
    ~A() {}
    int data;
};

int main() {
    const int NUMELEMENTS = 20;

    char *pBuffer = new char[NUMELEMENTS * sizeof(A)];
    A *pA = (A*)pBuffer;

    for (int i = 0; i < NUMELEMENTS; ++i) {
        pA[i] = new (pA + i) A();
    }

    std::cout << "Buffer address: " << pBuffer << ", Array address: " << pA << std::endl;

    // Remember to manually destroy each element
    for (int i = 0; i < NUMELEMENTS; ++i) {
        pA[i].~A();
    }

    delete[] pBuffer;

    return 0;
}
Copier après la connexion

Quelle que soit l'approche adoptée, il est crucial de détruire manuellement chaque élément du tableau avant de supprimer le tampon pour éviter les fuites de mémoire.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal