Frage

Ich habe eine Klasse gesehen, die eine Klasse ist, die wie folgt definiert ist ..

class StringChild : public StringBase
    {
public:
    //some non-virtual functions
    static StringChild* CreateMe(int size);
private:
    unsigned char iBuf[1];
    };

Die statische Factory-Funktion hat die folgende Implementierung ..

return new(malloc(__builtin_offsetof(StringChild ,iBuf[size]))) StringChild();

So so weit wie ich es verstehe diese Funktion mit Platzierung neuer diese Klasse zu erweitern.

Ist das sicher nur, weil es nur 1 Mitglied ist, und es ist auf dem Heap zugewiesen?

War es hilfreich?

Lösung

Es ist ein alter C Trick, der verwendet wurde, im Klar C. Ja um den Nicht-availablity variabler Länge Arrays zu arbeiten, funktioniert es auch in C ++, solange Sie geeignete allocator Konstrukte verwenden (wie ein Bündels von rohem Zuweisen von Speicher der gewünschte Größe und dann das Objekt newing Platzierung in dort). Es ist sicher, solange Sie nicht über das Ende des zugewiesenen Speicher wandern, aber es neigt zumindest einige Speicher Debugger zu verwirren.

Eine Sache müssen Sie absolut sicher, wenn mit dieser Technik ist, dass die variable Länge Array das letzte Element in dem Objekt-Layout ist, sonst werden Sie über andere interne Variablen gehen.

Ich bin aber ein wenig skeptisch, was die Umsetzung der Fabrik-Funktion - I die ‚Größe‘ Parameter übernehmen ist tatsächlich die gewünschte Array-Größe? Auch nicht vergessen, dass Sie den Speicher freizugeben müss oben ‚frei‘ und nicht mit ‚Löschen‘, obwohl diese vielleicht in den meisten Fällen funktioniert.

Es sei denn, es gibt einen zwingenden Grund, warum der Speicher auf diese Weise werden muss verwaltet werden, würde ich einfach ersetzen das Array mit einem std :: vector.

Andere Tipps

Dies sollte in Ordnung sein für PODs vorgesehen IBuf das letzte Mitglied der Struktur. Die Probleme mit nicht-PODs können, dass zB sein. Compiler kostenlose öffentliche / private / geschützte Mitglieder, virtuelle Basisklassen neu zu ordnen enden am Ende des am weitesten abgeleitete Objekt bis IIUC, etc.

Ihre Struktur ist nicht-POD (es hat eine Basisklasse), so würde ich es nicht empfehlen.

Auch wenn Sie Instanzen wie folgt erstellen

return new(malloc(__builtin_offsetof(StringChild ,iBuf[size]))) StringChild();

Sie sollten sicherstellen, dass der Speicher von malloc erworben sollten frei befreit werden, so löschen Sie Ihre Instanzen wie folgt aus:

obj->~StringChild();
free(obj);

Vielleicht möchten Sie ::operator new() für die Zuordnung verwenden

Genau genommen, da StringChild von StringBase abgeleitet ist, es ist nicht sicher. Die C ++ Standard nicht festgelegt, das Layout für Basisklasse Subobjekte. Paragraf 10 Absatz 3:

  

Die Reihenfolge, in der die Basisklasse Subobjekte in dem die meisten abgeleitetes Objekt zugeordnet sind, (1.8) ist nicht spezifiziert.

Wenn StringChild ein POD-Struktur waren, dann eine solche Technik wäre sicher.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top