类型转换长指针问题

时间:2013-04-04 16:20:53

标签: c++ c

  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);

3 个答案:

答案 0 :(得分:6)

那是演员。它说“我知道我在做什么,我想把这个char*视为long*”。之后,它会将i分配给第一个元素(相当于plMsgStart[0] = i;

根据long的大小,您将覆盖char数组中的前4个或8个元素。打印它仍然是未定义的行为,因为sBuffer不是以null开头的。

如果你做了

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

然后尝试打印sBuffer(在long覆盖之后),您将看到与500的二进制表示形式对应的4个(或8个)字符。

视觉

 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  |       |       |       |       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

答案 1 :(得分:2)

此代码创建一个名为sBuffer的20字节长缓冲区,然后在缓冲区的第一个n字节中存储值为500的long,其中n是字节数需要在您的系统上存储long

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

这一行告诉编译器你希望plMsgStartsBuffer是同一个内存块,但应该将该块视为存储long s。

答案 2 :(得分: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的值,如果你尝试访问它,你应该看到500;如果你试图访问sBuffer作为char(或char数组),你很可能会得到一个垃圾。这是typecast的一个完美原因,因为编译器不应该抱怨你做的任何事情,但是你只是溢出了你的字符数组的第一个元素(char需要值最多255)

您将500存储到该内存中,即:

0000 0001 1111 0100 2 如果以字节形式查看:

[00000001] [11110100] ==> [0x1] [ - 0x12](签名)                       

[00000001] [11110100] ==> [0x1] [0xF4](无符号)

因此,当您尝试打印该“字符串”时,您会看到垃圾(或者如果系统上charunsigned,则最多为'O')。