new で取得した char 配列にデータを格納する単純なバイト バッファを作成しています。memcpy および memmove 関数が、new で取得したメモリで使用すると奇妙なことが起こるかどうか、または代わりに推奨する何かがあるかどうか疑問に思っていました。 ?
5 に答える
memcpy()
/を使用memmove()
すると、その種のデータでうまく機能するはずです。一般に、どの POD タイプでも安全に使用できます。
いいえ、まったく問題ありません。new
とmalloc()
は、ヒープ上のメモリを取得できる 2 つの異なる方法です (実際には、ほとんどの実装で内部でnew
使用されるため、これらはまったく同じです)。malloc()
有効な変数を手元に持つとすぐに(またはスタック上にchar*
割り当てられます)、それはメモリへのポインタに過ぎないため、このファミリの他の関数は期待どおりに動作します。new
malloc()
memcpy()
char 配列データの場合、new と組み合わせても問題なく動作するはずです。
しかし、C++ では、std::copy または std::copy_backward を使用して、質問を完全に排除してみませんか?
new
それは実際には、プラットフォームと、コンパイラのおよびの実装に依存しますmemmove
。ほとんどのプロセッサ アーキテクチャでは、データをワード境界に揃えると、データのシャッフルが改善されますが、パフォーマンスが向上する追加のケースもあります。たとえば、PowerPC 7447 は、16 バイト境界に整列されたメモリで最も高速に動作します。これは、Altivec SIMD 命令セットのベクトル レジスタのサイズであるため、memcpy または同様の関数を実装して、16 バイト境界に割り当てられた配列でより高速に実行できます。例については、この質問を参照してください。
なぜこれが新しいものに違いをもたらすのですか?new 演算子は、割り当てられたメモリ ブロックに関するメタデータを、返されるポインターの数バイト前に格納できるため、実際のポインターは、割り当ての実際の先頭から 1 ワードまたは 2 ワード過ぎたものになります。私がこの動作に遭遇した CPU、OS、およびコンパイラ (PowerPC 7447a、VxWorks 5.5、GCC 2.95) では、new 演算子は、8 バイト アラインされているが 16 バイト アラインされていないブロックを提供することが保証されていました。もちろん、これは非常に実装固有です。アーキテクチャ固有の最適化になるため、アラインメントを指定する C++ 標準には何もないと思います。
これらすべてのポイントは、特定のプラットフォームを使用していて、アライメントなどの低レベルの最適化の問題を気にしている場合、パフォーマンスにわずかな違いが生じる可能性があるということです。ほとんどのアプリケーションでは、おそらくこれについて心配する必要はありません。
私はまだ std::copy で vector を使用しますが、それは new/memcpy/memmove が悪いという意味ではありません。バッファ内で部分を移動することを主張する場合は、 memmove が実際に優先されます。