Heim > Backend-Entwicklung > C++ > Ist die Verwendung von Placement New auf C-Arrays portabel?

Ist die Verwendung von Placement New auf C-Arrays portabel?

DDD
Freigeben: 2024-11-18 05:38:02
Original
707 Leute haben es durchsucht

Is Using Placement New on C   Arrays Portable?

Portable Placement New für Arrays

Der Placement-New-Operator der Standardbibliothek ermöglicht die Zuweisung von Speicher an einer angegebenen Adresse. Die Verwendung mit Arrays wirft jedoch Bedenken hinsichtlich der Portabilität auf, da es zu möglichen Diskrepanzen zwischen dem zurückgegebenen Zeiger und der übergebenen Adresse kommen kann.

Verstehen des Problems

Bei Verwendung der Platzierung neu für Bei Arrays stimmt der zurückgegebene Zeiger möglicherweise nicht mit der angegebenen Adresse überein. Dies wird in Anmerkung 12 von 5.3.4 des C-Standards erläutert. Folglich wird die Zuweisung eines Puffers speziell für das Array problematisch.

Betrachten Sie das folgende Beispiel:

#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;
}
Nach dem Login kopieren

Dieses Beispiel führt unter Microsoft Visual Studio häufig zu einer Speicherbeschädigung. Eine Untersuchung des Speichers zeigt, dass der Compiler der Array-Zuweisung vier Bytes voranstellt und damit wahrscheinlich die Anzahl der Array-Elemente speichert. Dieses Verhalten variiert je nach Compiler und verwendeter Klasse.

Portable Lösung

Um dieses Portabilitätsproblem zu beheben, vermeiden Sie die Verwendung von Placement New direkt auf Arrays. Erwägen Sie stattdessen, jedes Element des Arrays mithilfe der neuen Platzierung einzeln zuzuweisen:

#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;
}
Nach dem Login kopieren

Unabhängig vom gewählten Ansatz ist die manuelle Zerstörung jedes Array-Elements vor dem Löschen des Puffers von entscheidender Bedeutung, um Speicherlecks zu verhindern.

Das obige ist der detaillierte Inhalt vonIst die Verwendung von Placement New auf C-Arrays portabel?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage