7

私はATLのCComBSTRタイプを使用するいくつかの古いコードに取り組んでいます。ATLに付属していないVisualC++ExpressEditionを使用してコンパイルされるように変更しています。の非常に小さなサブセットのみを使用したCComBSTRので、これを行うのはかなり簡単です。

ただし、BSTRメモリブロックを割り当てるときは、最初の4バイトを4バイトの長さのプレフィックスで埋める必要があります。new char[size]式を使用して文字列にメモリを割り当てると、割り当てられたchar配列に4バイトのプレフィックスの正しい配置がないため、配置エラーが発生するのではないかと心配しています。

の戻り値にどのようなアライメント要件があるかを示す規格に何かありnewますか?C++11で表示されるのは次のとおりです。

5.3.4 / 1 [expr.new]
オーバーアラインされたタイプがサポートされているかどうかは、実装によって定義されます(3.11)。

3.11 / 6 [basic.align]
完全な型の配置要件は、alignof式(5.3.6)を使用して照会できます。さらに、タイプchar、signed char、およびunsigned charは、最も弱いアライメント要件を持つ必要があります。[注:これにより、文字タイプをアラインされたメモリ領域(7.6.2)の基になるタイプとして使用できるようになります。—end note]

これは少し紛らわしいと思います。「最も弱い位置合わせ要件」は「位置合わせに対する最も厳密な制約がない」と私に言いますが、この下の注記は、標準が反対を意味することを示しているようです。

new char[sizeof(uint32_t) + 2*(length + 1)]このようにバッファを使用しても安全BSTRですか?

編集:この特定のケースではBSTR、とにかく文字列を割り当てるためにSysAllocStringを使用する必要があることに気づきました。しかし、私はまだnewこのように使用しても大丈夫かどうかに興味があります。

4

3 に答える 3

7

これは実装の詳細ですが、MSVCはオペレーティングシステムのアロケータを使用します。CRT割り当ての場合はHeapAlloc()、_bstr_tなどのCOMタイプラッパーの場合はCoTaskMemAlloc()。これらは両方とも、32ビットと64ビットの両方のコードで8ずつ整列します。

新しい演算子を使用してBSTRにメモリを割り当てないでください。適切なヒープを使用してBSTRの割り当てを解除するには、COMアロケータを使用する必要があります。BSTRが使用される相互運用シナリオでは重要であり、これは標準の自動化タイプです。CoTaskMemAlloc / Free()が必要ですが、適切に初期化されるように、常にBSTRヘルパー関数を使用してください。SysAllocString()およびSysFreeString()。SysAllocStringLen()を使用して、埋め込まれたゼロを含む文字列を処理します。

于 2012-10-27T16:21:35.077 に答える
4

5.3.4 / 1 [expr.new]

オーバーアラインされたタイプがサポートされているかどうかは、実装によって定義されます(3.11)。

ここで重要なことの1つover-alignedは、どの組み込みタイプよりも整列していることを意味します。たとえば、64ビットマシンでは、ポインタは通常8バイトで整列されているため、これらのマシンでは、整列が厳密に8より大きいことを意味します。

したがって、over-alignedSSEまたはAVX命令、またはC / C ++の一部のバリアント(Open CLなど)に必要なベクトルタイプを使用する場合にのみ問題になります。日常のプログラミングでは、組み込みの型から作成する型が過度に整列されることはありません。

§3.11配置[basic.align]

3 /拡張アライメントは、より大きいアライメントで表されalignof(std::max_align_t)ます。拡張アライメントがサポートされているかどうか、およびそれらがサポートされているコンテキストは実装によって定義されます(7.6.2)。拡張アライメント要件を持つタイプは、オーバーアライメントタイプです。

9 /特定のコンテキストでの特定の拡張アライメントの要求が実装でサポートされていない場合、プログラムの形式が正しくありません。さらに、要求されたアライメントを受け入れることができない動的ストレージの実行時割り当ての要求は、割り当ての失敗として扱われるものとします。

newさらに、にアラインされたメモリを返すのが通例ですalignof(std::max_align_t)。これは、レギュラー::operator newが割り当てるオブジェクトのサイズのみを認識し、その配置を認識しないため、プログラムで可能な最も強力な配置要件を満たす必要があるためです。

一方、charスタックに割り当てられた配列に注意してください。その配列が最終的にどのようになるかは保証されません。

于 2012-10-27T14:05:24.003 に答える
0

BSTRにC++メモリ管理関数を使用しようとしないでくださいSysAllocString()。ファミリ関数を使用してのみ割り当てる必要があります。これにより、取得した人は誰でも、取得した家族の機能やその他の機能をBSTR使用できるようになります。この要件に違反すると、プログラムは未定義の動作に遭遇します。SysFreeString()BSTR

于 2012-10-29T12:30:28.370 に答える