Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类型转换长指针问题_C++_C - Fatal编程技术网

C++ 类型转换长指针问题

C++ 类型转换长指针问题,c++,c,C++,C,最后一行是否在字符数组中指定了500?但当我打印数组时,会得到垃圾值 下面的Hyth-Bes是实际代码,当我把代码从C++转换成C时,遇到了这个代码,下面的代码是C++函数的一部分,现在函数下面给出了垃圾值? char *sBuffer=new char[20]; char * sStringStart = sBuffer; long * plMsgStart = (long *) sBuffer;// what is this line doing long i

最后一行是否在字符数组中指定了500?但当我打印数组时,会得到垃圾值

下面的Hyth-Bes是实际代码,当我把代码从C++转换成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

那是演员阵容。它说我知道我在做什么,我想把这个字符*当作一个长字符*。之后,它将i分配给与plMsgStart[0]=i;等效的第一个元素

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

如果是的话

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);
然后在长时间覆盖后尝试打印sBuffer,您将看到4或8个字符对应于500的二进制表示形式

视觉的

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

那是演员阵容。它说我知道我在做什么,我想把这个字符*当作一个长字符*。之后,它将i分配给与plMsgStart[0]=i;等效的第一个元素

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

如果是的话

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);
然后在长时间覆盖后尝试打印sBuffer,您将看到4或8个字符对应于500的二进制表示形式

视觉的

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

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

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

这一行告诉编译器,您希望plMsgStart与sBuffer是同一个内存块,但该块应被视为存储long。

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

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

这一行告诉编译器,您希望plMsgStart与sBuffer是同一个内存块,但应该将该块视为存储long。

…我不确定如何使其更简单,但我会尝试:

long * plMsgStart = (long *) sBuffer;// what is this line doing
这使得plMsgStart指向sBuffer

所以实际上,sBuffer指向的内存被设置为500,如果你尝试长时间访问它,你会看到500;如果您试图以char或char数组的形式访问sBuffer,很可能会得到一个垃圾。这是一个不这样做的完美理由,因为编译器不应该抱怨您所做的任何事情,但您只是溢出了字符数组的第一个元素char的值高达255

您在该内存中存储了500,即:

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

[00000001][11110100]==>[0x1][0x12]已签名 或 [00000001][11110100]==>[0x1][0xF4]未签名


因此,当您试图打印该字符串时,您看到的是垃圾,如果系统中的字符未签名,则最多只能看到一个“O”

…我不知道如何使它更简单,但我会尝试:

long * plMsgStart = (long *) sBuffer;// what is this line doing
这使得plMsgStart指向sBuffer

所以实际上,sBuffer指向的内存被设置为500,如果你尝试长时间访问它,你会看到500;如果您试图以char或char数组的形式访问sBuffer,很可能会得到一个垃圾。这是一个不这样做的完美理由,因为编译器不应该抱怨您所做的任何事情,但您只是溢出了字符数组的第一个元素char的值高达255

您在该内存中存储了500,即:

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

[00000001][11110100]==>[0x1][0x12]已签名 或 [00000001][11110100]==>[0x1][0xF4]未签名


因此,当您试图打印该字符串时,您看到的是垃圾,如果系统中的字符未签名,则最多只能看到一个“O”

假设它不是疯狂的,那么第一个sizeoflong字符将被视为一个长变量,并设置为500。取决于数据的存储方式。是的,它看起来像垃圾,但通过它,你可以看到“500”是如何存储的。假设它不疯狂,第一个sizeoflong字符被视为一个长变量,并设置为500。取决于数据的存储方式。是的,它看起来像垃圾,但通过它,你可以看到'500'是如何存储的。我认为整个事情都是UB,因为它违反了类型别名规则。也许还有一个对齐问题……我想是的;它通过一个指向不兼容类型的指针访问对象,我从C中的规则略微推断出来,也许C++中的规则不同。至于对齐,这当然可能是一个问题,这取决于您的平台允许什么。@OliCharlesworth我认为new返回一个正确对齐的单词大小指针。我不确定不是,但是

我对此表示怀疑。是否保证对齐?但为什么打印%s,sBuffer;给出垃圾值。我认为整个过程都是UB,因为它违反了类型别名规则。也许还有一个对齐问题……我想是的;它通过一个指向不兼容类型的指针访问对象,我从C中的规则略微推断出来,也许C++中的规则不同。至于对齐,这当然可能是一个问题,这取决于您的平台允许什么。@OliCharlesworth我认为new返回一个正确对齐的单词大小指针。我不确定它是否正确,但我对此表示怀疑。是否保证对齐?但为什么要打印%s,sBuffer;给出垃圾值。因为它是一个数组,并且他将其强制转换为long类型,所以第一个sizeoflong将容纳500?。而char应该是-128到127?@Koushik,至少在大多数系统上,第一部分你是对的。关于字符,标准没有定义普通字符是有符号的还是无符号的。因此,正确的范围是CHAR\u MIN到CHAR\u MAX。@谢谢您的更正。那么“字符符号是实现定义的吗?”@Koushik-数组只是一组连续的字节。字符的大小是1字节,长字符的大小取决于您的系统,但8字节是安全的。因此,从技术上讲,可以将long存储到大小为20的字符数组中,并将其作为long进行访问。但这毫无意义。。。20字节只能存储2个完整长度。。WRT字符所能容纳的值,字符所能容纳的最大值是255,所以我提到了number@Mike我同意这一点,但是你的sBuffer的第一个元素被设置为500,这是我在评论的时候想到的。因为它是一个数组,他将它转换为长类型,第一个sizeoflong将容纳500?。而char应该是-128到127?@Koushik,至少在大多数系统上,第一部分你是对的。关于字符,标准没有定义普通字符是有符号的还是无符号的。因此,正确的范围是CHAR\u MIN到CHAR\u MAX。@谢谢您的更正。那么“字符符号是实现定义的吗?”@Koushik-数组只是一组连续的字节。字符的大小是1字节,长字符的大小取决于您的系统,但8字节是安全的。因此,从技术上讲,可以将long存储到大小为20的字符数组中,并将其作为long进行访问。但这毫无意义。。。20字节只能存储2个完整长度。。WRT字符所能容纳的值,字符所能容纳的最大值是255,所以我提到了number@Mike我同意这一点,但是您的sBuffer的第一个元素被设置为500是我在评论时想到的。但是为什么printf%s,sBuffer;提供垃圾值,因为%s需要一个包含ASCII值的字节数组,后跟一个值为0的字节。如果要打印出500,则需要printf%ld,plMsgStart[0];但是为什么要打印%s,sBuffer;提供垃圾值,因为%s需要一个包含ASCII值的字节数组,后跟一个值为0的字节。如果要打印出500,则需要printf%ld,plMsgStart[0];