1
  char *sBuffer=new char[20];
    char * sStringStart = sBuffer;

    long * plMsgStart = (long *) sBuffer;// what is this line doing

    long i=500;

    *plMsgStart = i // what is this line doing

最後の行は char 配列に 500 を割り当てていますか? しかし、配列を印刷すると、ガベージ値が取得されます

以下は実際のコードで、コードを C++ から C# に変換しているときに遭遇しました。このコードは C++ 関数の一部ですが、なぜ以下の関数がガベージ値を与えるのですか?

char *sBuffer=new char[20];
char * sStringStart = sBuffer;
BSTR bsMsgBody= SysAllocString(L"Helo");
sStringStart+=4;
long * plMsgStart = (long *) sBuffer;

long l=50;

*plMsgStart=l;

sprintf(sStringStart, "%S", bsMsgBody);

printf("%S",sBuffer);
4

3 に答える 3

6

それがキャストです。「私は自分が何をしているのか知っています。これchar*をあたかもそれであるかのように扱いたい」と書かれていlong*ます。iその後、最初の要素に代入します ( plMsgStart[0] = i;.

のサイズに応じて、配列longの最初の 4 つまたは 8 つの要素を上書きします。最初は null で終了していなかっcharたため、印刷はまだ未定義の動作です。sBuffer

あなたがした場合

 char *sBuffer=new char[20]();

sBuffer(上書き後)印刷しようとlongすると、 のバイナリ表現に対応する4(または8)文字が表示され500ます。

ビジュアル

 char *sBuffer=new char[20];

 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | | | | | | | | | | | | | | | | | | | | |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

 long * plMsgStart = (long *) sBuffer;

 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |       |       |       |       |       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                 ^^^^^
    note this is still the same memory,
   but "seen through the eyes" of a long*


 *plMsgStart = 500;

 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |  500  |       |       |       |       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
于 2013-04-04T16:23:03.103 に答える
2

...もっと簡単にする方法はわかりませんが、試してみます。

char *sBuffer // sBuffer is a pointer to a character type

long * plMsgStart  // plMsgStart is a pointer to a long type

(long *) sBuffer;// this tells the compiler that I want my char pointer to be treated
                 // as a long pointer during this assignment.

これにより、plMsgStartが を指しているようになりsBufferます。

*plMsgStart = i; // this is dereferencing the pointer, it says: 
                 // "at the current memory location" store the value i

実際には、 が指すメモリにsBufferは の値が設定されています。500これに long としてアクセスしようとすると、500が表示されます。sBufferchar (または char 配列) としてアクセスしようとすると、ガベージが発生する可能性が高くなります。これはtypecastをしない完全な理由です。なぜなら、コンパイラはあなたがしたことについて不平を言うべきではありませんが、文字配列の最初の要素をオーバーフローさせただけです (最大 255 の値を取ります)char

そのメモリに 500 を格納すると、次のようになります。

0000 0001 1111 0100 2これをバイト形式で見ると:

[00000001] [11110100] ==> [0x1][-0x12] (符号付き)
または
[00000001] [11110100] ==> [0x1][0xF4] (符号なし)

したがって、その「文字列」を印刷しようとすると、ゴミが表示されます (または、システム上にある場合charはせいぜい「O」 unsigned)。

于 2013-04-04T16:29:14.557 に答える
2

このコードは、 という 20 バイト長のバッファーを作成し、バッファーの最初のバイトにsBuffer値 500 の long を格納します。ここで、 はシステムに を格納するために必要なバイト数です。nnlong

long * plMsgStart = (long *) sBuffer;// what is this line doing

plMsgStartこの行は、と同じメモリ ブロックになりたいことをコンパイラに伝えるものですsBufferが、ブロックは s を格納しているかのように扱われるべきlongです。

于 2013-04-04T16:24:59.130 に答える