2016-11-03 5 views
1

別のアロケータ(通常は内部的にreallocを呼び出します)によって返されたメモリに任意のC++オブジェクトを構築します。私はmalloc'edメモリに新しい配置を行うのは一般的にうまくいることを知っています。しかし、私は、すべてのC++オブジェクトが連続して割り当てられたメモリの前に別の共通オブジェクトを持つことを望みます。このヘッダーオブジェクトには、次のC++オブジェクトに関する情報が含まれます。私はそれが整列の観点から(sizeof(header)+ sizeof(type))メモリを割り当て、(mem + sizeof(header))で型を構築するのが安全だとは知らない。私は、(mem + sizeof(header))が型のために正しく整列されていることが保証されていないためではないと思います。ヘッダオブジェクトを使ってmallocされたメモリにC++オブジェクトを安全に構築する方法

私は、タイプTの後ろにヘッダを宣言し、sizeof(ObjPlusHeader<T>)を割り当てるテンプレートタイプを生成する可能性があると考えています。しかし、問題は、構造体が私のコードの別の部分にボイド*(私がコントロールしていない外部ライブラリによって義務づけられている)として現れるので、何をキャストするかを知っていなければならないということです。私はObjectPlusHeader<???>*にヘッダー*にキャストしたいです。

標準レイアウトタイプでは、最初のメンバーへのポインタにオブジェクトをキャストできます。ただし、Tが必ずしも標準レイアウトであるとは限りません。この場合、ヘッダがある場合でもObjectPlusHeader<T>は標準レイアウトになりません。私はまた、Tを含む代わりにTからヘッダーからプライベートにラッパー・テンプレートを生成することも検討しました。しかし、格納された実際の型に最初にキャストすることなく、void *を直接Header *にキャストできません私は知らない。

アロケータによって割り当てられた連続したメモリ(本質的にrealloc)は、私が知っているところではヘッダが先頭にあり、任意のC++オブジェクトは、私が知っている、適切に整列したアドレス> = mem + sizeof(Header)ヘッダーに格納します。 void *を与えられれば、それをHeader *にキャストしてオブジェクトを取得できます。しかし、私は潜在的なアラインメントの問題については確信していません。

+0

オブジェクトが一緒に縛らあなたは 'のstd :: pair' – NathanOliver

+0

@NathanOliverとして保存する必要がある場合。実際には、Tが必ずしも標準レイアウトではない場合、標準::: *をヘッダーにキャストすることは安全ですか?あなたは、問題の第二の部分は私がペアの実際のタイプを知らないということです。ヘッダー*にキャストしてそこから移動できるという保証が必要です。 – authentec

+1

あなたは[alignof](http://en.cppreference.com/w/cpp/language/alignof)で必要なアライメントを取得し、それに応じてポインタを調整するだけですか?すなわち、正しい量のパディングを自分で追加します。 –

答えて

2

ちょうど適切なパディングを計算する(constexprの)関数を記述します。

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

は割り当て:

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

Slavaの提案に感謝します。割り当てはどのように見えますか? malloc(sizeof(std :: pair ))?編集:私は、私はmalloc(sizeof(ヘッダー)+ offsetAfterHeader ()+ sizeof(t)を行う必要があります参照してください) – authentec

+0

@authentec良い質問は、実際には、よりパッディングを計算するために使用可能です。 – Slava

+0

*個人的には、私は 'template size_t SizeofHeaderRoundedUp(returnof sizeof(Header)+ alignof(T)-1))/ alignof(T)* alignof(T);と書いています。 } ' - 多分もっと多くの行があります。 –

1

あなたは最大アラインメントとヘッダを宣言する場合は、あなたが心配する必要はありません追加の位置合わせを必要とする物体の後に続く。私のシステムで

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

、出力は次のようになります。

size: 32 
align: 16 
関連する問題