7
int a = 10;
int* pA = &a;
long long b = 200;
long long* pB = &b;

memcpy (pB,pA,4);
memcpy (pB+1,pA,4);

cout<<"I'm a memcpy!: "<<*(pB)<<endl;

私は memcpy でいくつかのテストを行って、メモリの仕組みを自分自身に教えています。私がやろうとしているのは、b = を "1010" にすることです。a から b に値をコピーできますが、メモリを 1 バイトオフセットして別の 10 を書き込もうとしますが、「10」しか出力されません。

1010 の値を取得するにはどうすればよいですか?

4

7 に答える 7

9

現状のコードに関するいくつかの問題:

  • 4バイトをコピーしますが、宛先はタイプintです。特定のサイズであることが保証されていないためint、そのようなサイズを実行する前に、少なくとも4バイトの長さであることを確認する必要がありますmemcpy
  • memcpyバイトレベルで機能しますが、整数は一連のバイトです。ターゲットアーキテクチャに応じて、整数内のバイトは異なる方法で配置される場合があります(ビッグエンディアン、リトルエンディアンなど)。整数で使用memcpyすると、期待どおりの結果が得られる場合と得られない場合があります。memcpy友達がどのように機能するかを学ぶときは、バイト配列を使用するのが最善です。
  • 2番目memcpypB+1ターゲットとして使用します。これはポインタを1バイト進めるのではなく、sizeof(*pB)バイト単位で進めます。この場合、それは無効なアドレス(変数の終わりを過ぎた)を指しているままになります。このを呼び出すとmemcpy、ランダムメモリが破損し、プログラムがクラッシュしたり、予期しない結果が発生したりする可能性があります。
于 2012-06-14T00:05:27.010 に答える
2

memcpy()あなたが望むもののために設計されているとは思いません。一般に、memcpy()1 つまたは複数のオブジェクト全体 (オブジェクトは int、char、long long など) をコピーするために使用します。

    int a[4] = { 1, 2, 3, 4 };
    int b[3];
    int c[5] = { 0 };

    ::memcpy(b, a, 3 * sizeof(int));   // b is { 1, 2, 3 }
    ::memcpy(c+2, b, 3 * sizeof(int)); // c is { 0, 0, 1, 2, 3 }

c+2 は「c + 2 バイト」ではありません。「c + 2 int」(Win32/x86 システムでは 8 バイト) です。

char または unsigned char ポインターにキャストすることで個々のバイトにアクセスできますが、多くの落とし穴があるため、何をしているのかを本当に理解している場合を除き、お勧めしません。

    unsigned x = 0;
    unsigned char *px = reinterpret_cast<unsigned char *>(&x);

    px[0] = 0xFF;
    px[2] = 0xAA;

ここでの危険の 1 つは、コンピューターが整数を格納する方法についての知識を前提としていることです。x86 システムでは x は 0x00AA00FF になりますが、Sun Sparc システムでは 0xFF00AA00 になります。

整数の一部を設定する必要がある場合は、"or" と "shift" を使用する方がよい場合がよくあります。

    x = (0xFF<<24) | (0xAA<<8);

どのアーキテクチャでも 0xFF00AA00 が返されます。0xFF<<24 は、値 0xFF を 24 ビット左にシフトし、0xFF000000 にします。0xAA<<8 は、値 0xAA を左に 8 ビットシフトし、0x0000AA00 にします。

それらを「or」して、0xFF00AA00 を与えます。

于 2012-06-14T00:30:09.083 に答える
1

ポインタ演算を調べます:http ://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html 。ポインタに値を追加すると、実際には、処理しているサイズに関係なく、その数だけ増加します。

于 2012-06-14T00:03:16.317 に答える
0

pBはlonglong*型であるため、それに1を追加すると、変数bに続く8バイトの次のセットにアドレスが与えられます。pB [0]が変数bですが、pB [1](pB + 1と同等)は未定義のメモリを指しています。これに書き込むと、クラッシュが発生する可能性があります。

交換

long long b;

long long b[2];

(好きな初期値を使用してください)

あなたのcoutはb[0]とb[1]の両方を与える必要があります。

于 2012-06-14T00:05:04.577 に答える