2

新しい配置、エイリアシング、パディング、配置に関するドキュメントを読んでいるのは久しぶりですが、それでもこの問題を解決する方法がわかりません-このレベルでメモリの問題に直面するのは初めてなので、自信がありません。

問題は次のとおりです。バッファ、データの配列があり、これはあるタイプを使用しますtypeT

typeT buff[N];

そのバッファ内に、タイプのその他のデータtypeUをの先頭に格納する必要がありbuffます。Kの要素があると仮定しましょう。これは、タイプの要素typeU以下です。MtypeT

編集:この問題はデータ型によって異なりますが、私の質問は一般的であり、PODと非PODに当てはまります。ただし、非PODはPODタイプの単なる集約であり、コピーされる動的メモリはなく、すべてのデータはsizeof(typeX)構造自体のバイト内に含まれていると想定できます。つまり、深い/浅いコピーについて心配する必要はありません

私は主に、typeTtypeUが異なる配置を持っている場合に興味があります。どのアライメントサイズが大きいかは不明です。

質問1 :(最も重要な質問)次のコードのように、typeUを使用してこれらのデータに常にアクセスするという事実を考慮すると、データを格納するために新しい配置を使用することは常に安全ですか?buff

typeU *allocData = new (buff) typeU[K];
allocData[0] = foo;

質問2:次のコードのように、を使用して常にデータにアクセスすることを考えると、を使用してタイプのバッファ内からデータをコピーすることは常に安全ですか?typeU*typeT*memcpytypeU*

typeU prevData[K];
memcpy(buff, prevData, sizeof(typeU) * K);
// Is it safe to do the following?
typeU *accessData = reinterpret_cast<typeU *>(buff);
accessData[1] = foo;

質問3 :(最も重要でない質問)ポインタをキャストしてそれらを使用してデータを書き込むことが常に安全であるとは限らないというのは本当ですか?のように

typeU *castData = (typeU*)buff;
castData[2] = something;

常にメモリの最初の領域(最初のM要素)を使用typeUし、2番目の領域(MからNまでの要素)を使用している場合でも、 typeT

意味がはっきりしているといいのですが…たくさん検索しましたが、まだ戸惑っています。

また、STLのサブセットが最小限で、ブーストがなく、常にx86であるとは限らない、11ではなくC ++ 98または03について話していることを考慮してください。ただし、前述のように、memcpyとplacementnewを使用できます。

4

2 に答える 2

3

typeTと のサイズとアラインメントの要件typeUが同じであれば、 に割り当てられた初期化されていないストレージを使用typeTして の値を保持できますtypeU

typeTおよび/またはコンストラクタまたはデストラクタがある場合typeUは、それらが適切に正しい順序で呼び出されるようにする必要があります。

static_assert(sizeof(typeT) == sizeof(typeU))
static_assert(alignof(typeT) == alignof(typeU))

typeT t[10];

&t[0]->~typeT(); // placement delete t[0] to uninitialize
typeU* p = &t[0];
new (p) typeU(); // construct typeU at t[0]

typeU u& = *p;

u.doStuff();

p->~typeU(); // placement delete typeU at t[0]

new (&t[0]) typeT(); // reconstruct typeT at t[0]
于 2013-03-20T23:50:46.210 に答える
0

私が知らなかったことを紹介する Sutter によるこの記事を発見しました

new または malloc によって動的に割り当てられたメモリは、あらゆるタイプのオブジェクトに対して適切に整列されることが保証されますが、動的に割り当てられないバッファにはそのような保証はありません

これは、まず第一に、私がしていたようにすることは間違っていることを意味します:

typeT buff[N];
new (buff) typeU[K];

バフは動的に割り当てられないため、保証はありません。

つまり、ポイントは、この種の処理を行うには、メモリを動的に割り当てる必要があるということです。そうでない場合、答えはアラインメントによって異なります。

于 2013-03-21T10:49:50.843 に答える