2016-11-03 3 views
1

Ich möchte beliebige C++ - Objekte im Speicher von einem anderen Zuordner (die in der Regel realloc intern ruft) erstellt werden. Ich weiß, dass es in der Regel gut ist, ein Placement neu in Malloc'ed Memory zu machen. Ich möchte jedoch, dass alle C++ - Objekte ein anderes gemeinsames Objekt davor in zusammenhängendem zugewiesenem Speicher haben. Dieses Header-Objekt enthält Informationen zum folgenden C++ - Objekt. Ich weiß nicht, dass es vom Ausrichtungsstandpunkt aus sicher ist, (sizeof (header) + sizeof (type)) Speicher zuzuweisen und dann den Typ bei (mem + sizeof (header)) zu konstruieren. Ich denke, es ist nicht so, weil (mem + sizeof (header)) nicht garantiert ist, dass sie richtig auf den Typ ausgerichtet sind.Wie ein C++ - Objekt in malloced Speicher mit einem Header-Objekt sicher zu erstellen

Ich habe Möglichkeiten wie das Generieren eines Schablonentyps, der die Kopfzeile gefolgt von Typ T deklariert und sizeof(ObjPlusHeader<T>) zuweist. Das Problem ist jedoch, dass die Struktur in einem anderen Teil meines Codes als void * erscheinen wird (von einer externen Bibliothek, die ich nicht kontrolliere, beauftragt), also muss ich wissen, auf was ich sie anwenden soll. Ich möchte in Header * nicht in ObjectPlusHeader<???>* umwandeln.

Ich weiß mit Standard-Layout-Typen kann ich ein Objekt auf einen Zeiger auf sein erstes Mitglied zu werfen. T ist jedoch nicht unbedingt Standardlayout. In diesem Fall wird ObjectPlusHeader<T> nicht Standard Layout sein, auch wenn Header ist. Ich überlegte auch, die Wrapper-Vorlage aus Header und privat aus T öffentlich abzuleiten, anstatt T zu enthalten. Es wäre jedoch immer noch nicht legal, das void * direkt in einen Header * zu werfen, ohne zuerst auf den tatsächlichen Typ zu werfen, der gespeichert wurde Ich werde es nicht wissen.

Was ich will ist zusammenhängender Speicher durch den Zuordner (im Wesentlichen Realloc) zugeordnet, wo ich weiß Header ist am Anfang und das beliebige C++ Objekt folgt bei einigen richtig ausgerichteten Adresse> = mem + sizeof (Header), die ich kenne und kann in der Kopfzeile speichern. Wenn ich also die Leere * habe, kann ich sie in Header * umwandeln und das Objekt erhalten. Ich bin jedoch unsicher bezüglich der möglichen Ausrichtungsprobleme.

+0

Wenn die Objekte miteinander verbunden werden, sollten Sie sie als 'std :: speichern pair' – NathanOliver

+0

@NathanOliver. In der Tat, aber ist es sicher, std :: pair * in Header * zu schreiben, wenn T nicht unbedingt Standard Layout ist? Sie sehen, der zweite Teil des Problems ist, dass ich den tatsächlichen Typ des Paares nicht kennen werde. Ich brauche eine Garantie, dass ich in Header * umwandeln kann und von dort aus gehe. – authentec

+1

Warum erhalten Sie nicht einfach die erforderliche Ausrichtung über [alignof] (http://en.cppreference.com/w/cpp/language/alignof) und passen den Zeiger entsprechend an? d. h., fügen Sie die richtige Menge an Polsterung selbst hinzu. –

Antwort

2

schreiben Sie einfach eine (constexpr) Funktion richtige Polsterung zu berechnen:

template<typename T> 
size_t paddingAfterHeader() { 
    auto rem = sizeof(Header)%alignof(T); 
    return rem ? alignof(T) - rem : 0; 
} 

Zuordnung:

void *mem = malloc(sizeof(Header) + paddingAfterHeader<T>() + sizeof(T)); 
+0

Danke für den Vorschlag Slava. Wie sieht die Zuordnung aus? malloc (sizeof (std :: Paar ))? Edit: Ich sehe, ich sollte malloc tun (sizeof (Header) + offsetAfterHeader () + sizeof (t)) – authentec

+0

@authentec Gute Frage, eigentlich wäre es mehr nützlich, Padding zu berechnen, behoben. – Slava

+0

* Persönlich würde ich 'Schablone schreiben size_t SizeofHeaderRoundedUp() {Rückkehr (sizeof (Vorsatz) + alignof (T) -1))/alignof (T) * alignof (T); } '- wahrscheinlich mit mehr Zeilen. –

1

Wenn Sie den Header mit maximaler Ausrichtung deklarieren, müssen Sie sich nicht um die Sorgen folgendes Objekt, das eine zusätzliche Ausrichtung erfordert.

#include <cstddef> 

struct 
alignas(std::max_align_t) 
Header 
{ 
    char body[17]; 
}; 

#include <iostream> 

int main() 
{ 
    std::cout << "size: " << sizeof(Header) << std::endl; 
    std::cout << "align: " << alignof(Header) << std::endl; 
} 

Auf meinem System ist die Ausgabe:

size: 32 
align: 16 
Verwandte Themen