Neue Platzierung für Arrays: Bedenken hinsichtlich der Portabilität
In C ermöglicht die neue Platzierung die Speicherzuweisung an einer angegebenen Adresse. Allerdings bringt die Verwendung für Arrays Probleme mit der Portabilität mit sich. Dieser Artikel untersucht das Problem und stellt eine tragbare Lösung vor.
Es wird oft angenommen, dass der von new[] zurückgegebene Zeiger mit der angegebenen Adresse übereinstimmt. Der C-Standard (5.3.4, Anmerkung 12) weist jedoch darauf hin, dass dies möglicherweise nicht der Fall ist. Dies stellt ein Problem dar, wenn versucht wird, mithilfe von „Placement New“ einen Puffer für ein Array zuzuweisen.
Der folgende Code veranschaulicht dieses Problem:
#include <new> #include <stdio.h> class A { public: A() : data(0) {} virtual ~A() {} int data; }; int main() { const int NUMELEMENTS = 20; char* pBuffer = new char[NUMELEMENTS * sizeof(A)]; A* pA = new(pBuffer) A[NUMELEMENTS]; printf("Buffer address: %x, Array address: %x\n", pBuffer, pA); delete[] pBuffer; // Assertion failure due to heap corruption return 0; }
Eine Untersuchung des Speichers zeigt, dass einige Compiler (z. B. Visual Studio) weisen vor dem Array zusätzliche Bytes für die interne Buchhaltung zu (z. B. eine Anzahl von Array-Elementen). Dies kann zur Heap-Beschädigung führen.
Es stellt sich die Frage: Können wir den Overhead bestimmen, der mit der Platzierung neuer Arrays für verschiedene Compiler verbunden ist? Ziel ist es, eine tragbare Lösung zu finden.
Vorgeschlagene Lösung
Anstatt die Platzierung neu für das gesamte Array zu verwenden, besteht eine mögliche Problemumgehung darin, jedes Array-Element einzeln zuzuweisen:
int main(int argc, char* argv[]) { 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(); } printf("Buffer address: %x, Array address: %x\n", pBuffer, pA); // Manual destruction for (int i = 0; i < NUMELEMENTS; ++i) { pA[i].~A(); } delete[] pBuffer; return 0; }
Diese Methode steuert explizit die Platzierung jedes Objekts im Array und stellt sicher, dass die Zerstörung korrekt durchgeführt wird.
Schlussfolgerung
Verwendung der Platzierung new für Arrays erfordert eine sorgfältige Berücksichtigung des Compiler-spezifischen Overheads. Die vorgeschlagene Lösung bietet eine portable Alternative, indem Array-Elemente einzeln zugewiesen und zerstört werden.
Das obige ist der detaillierte Inhalt vonIst die Platzierung neuer Arrays in C wirklich portabel?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!