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,您将覆盖char数组中的前 4 个或 8 个元素。打印它仍然是未定义的行为,因为sBuffer开始时没有以空值终止。

如果你做了

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

然后尝试打印sBufferlong覆盖后),您将看到 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

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

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

这一行告诉编译器你想plMsgStart成为与 相同的内存块sBuffer,但该块应该被视为存储longs。

于 2013-04-04T16:24:59.130 回答
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为 如果您尝试以char(或 char 数组)的形式访问,您很可能会得到垃圾。这是不进行类型转换的完美理由,因为编译器不应该抱怨你所做的任何事情,但你只是溢出了字符数组的第一个元素(取值高达 255)sBufferchar

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

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

[00000001] [11110100] ==> [0x1][-0x12](有符号)

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

因此,当您尝试打印该“字符串”时,您会看到垃圾(或者如果您的系统上有一个“O” charunsigned

于 2013-04-04T16:29:14.557 回答