0

直接割り当て (すなわち =) は、何かをキャストしてからchar*、ループを使用しforてバイトごとにコピーするのと同じですか? *
ある方法が他の方法よりも優れているかどうかを知りたい。

struct A
{
    int a;
    int b;
} Test;

void* Buffer = malloc(1024);


// Casting and byte copying
for (int i=0; i != 8; i++)
{
    ((char*)Buffer)[i] = ((char*)Test)[i];
}

// Assignment
((A*)Buffer)[0] = Test;

* すべての型はビットごとにコピー可能です。

編集:回答に基づいて、memcopyは「=」と同じです

4

4 に答える 4

10

これは基本的に何をするものであり、 POD タイプmemcpyに有効です(実際には 8 であると仮定します)。ただし、コンパイラには特別に最適化されたアセンブラ ルーチンがあるため、ほぼ確実に高速になります。sizeof(Test)memcpy

これ (または) を POD 以外の型で試すと、未定義の動作が発生します。memcpyしたがって、一般に、std::copy割り当てを使用するか、単に使用する必要があります。

mallocタイプセーフではないため、C++でも避ける必要があります。new必要に応じて、または配置newを使用してください。

于 2012-06-27T14:33:35.617 に答える
1

まず、これは C++ ではありません。これは醜い C です。1024 バイトのサイズのメモリ ブロックを手動で割り当て、そのアドレスをネイキッド ポインターにキャプチャしています。また、コード サンプルでは、​​いずれも解放せず、MB のメモリ リークが発生します。これは、C++ に関しては非常に悪い習慣と見なされます。

C++ はクラスを持つ C ではありません。標準ライブラリと組み合わせて使用​​し、OO プログラミング、特に RAII の概念、一般的なカプセル化の概念に自然に付随するより良い設計パターンに準拠することによってのみ、それ自体を表現できる美しい言語です。より良いメモリ管理で。ましてやnew不要な時は回避されるmalloc

for (int i=0; i != 8; i++)

また、ここで危険な仮定をしているため、未定義の動作につながる可能性があります。

((char*)Buffer)[i] = ((char*)Test)[i];

これについてはコメントするつもりもありません。なんてこった… 悪いだけでなく、うまくいかない。struct Aスタックに横たわっているインスタンス、通常の「オブジェクト」/var を強制的にchar*. がありません&Test

このパスを使用している場合は memcpy を使用しますが、C++ アプローチの改善を検討してください。memcpy は、宛先、ソース、およびバイト単位のサイズの 3 つの引数を取ります。2 つが一致していることを確認すると、バイトごとのコピーがすばやく取得されます。

于 2012-06-27T15:02:19.283 に答える
0

=演算子を使用した直接割り当ては、バイトをコピーするループとはまったく同じではありません。for演算子はタイプを尊重し、=それが何をするかはタイプによって異なります。また、ほとんどの場合、バイトごとのコピーは未定義の動作です。あなたの特定のケースでは、コンパイラがデータをunsigned long longとして扱い、それを1つか2つのマシン命令でコピーするのと同等の何かを生成することを期待します。しかし、それはあなたが定義したタイプの特殊性のためだけです。一般に、コンパイラーにできるだけ多くの情報を提供し、それを信頼します。それは通常あなたができるより良い仕事をするでしょう。

于 2012-06-27T15:08:49.143 に答える
0

これは、OP の質問に対する直接的な回答ではありませんが、彼が達成しようとしていると私が思うことに対する回答です。

フォーマットされたデータを転送可能なフォーマットに書き込むことはシリアル化であり、C++ ではこれを行う方法がいくつかあります。考慮すべき点がいくつかあります。形式は ascii、xml、バイナリである必要があり、バイナリの場合はクロスプラットフォーム (エンディアン、アライメント) である必要があります。いずれにせよ、構造体をバイト バッファにコピーする単純な方法は、ほとんど望ましくありません。

次のオプションを検討できます。

  • ascii 形式の可能性がある場合、最も簡単な方法は iostream を使用することです
  • ブースト.シリアライゼーション
  • 外部ライブラリ (公平に言えば、boost もその 1 つです): poco、google buffer protocol、...
  • 独自のロール (プリミティブの変換に基づく)

この質問も参照してください

于 2012-06-27T15:30:35.443 に答える