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; }
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; }
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!