Heim > Backend-Entwicklung > C++ > Hauptteil

Ist die Platzierung neuer Arrays in C wirklich portabel?

Mary-Kate Olsen
Freigeben: 2024-11-15 04:05:02
Original
533 Leute haben es durchsucht

Is Placement New for Arrays Truly Portable in C  ?

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

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

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!

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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage