为什么会编译? (unsigned char * thing =(unsigned char *)“ YELLOW SUBMARINE”;)

时间:2019-06-02 15:44:29

标签: c++

我正在努力理解为什么这一行代码有意义:

unsigned char *thing = (unsigned char *)"YELLOW SUBMARINE";

unsigned char保留一个字节的数据(即'Y'),因此unsigned char*应该是指向该单个字节数据的指针。

如果我尝试在其中放置多个字符,那么我认为编译器应该很生气。但是,我不介意在此处放置16个字节并告诉编译器我只指向一个unsigned char。有人可以解释一下吗?

我的想法是,编译器将为一个unsigned char分配内存,然后将整个字符串写入其中,覆盖相邻的内存并造成破坏。但是我以后可以正确地取消引用该指针并检索整个字符串,因此似乎没有问题。

上下文:我正在尝试将字符串转换为这种形式(unsigned char *)。

谢谢!

2 个答案:

答案 0 :(得分:1)

首先,如果C ++中的指针类型为unsigned char *,则基本上只告诉编译器以下内容:

  • 在取消引用指针时,编译器应仅从内存中读取一个字节,然后我们将该字节视为0到255之间的数字。(如果您的系统非常不寻常,那么这些规则可能会有所不同。)< / li>
  • 进行指针加减时,指针所指向的元素的大小为1(或系统上的sizeof(unsigned char)都为该数字。)

如果您查看严格的别名和内存对齐的概念,指针的类型也会产生一些微妙的影响,但是我不想对此进行详细介绍。

接下来,指针的类型不会告诉编译器指针是否具有可以取消引用的有效值。指针可能未初始化。它可能指向较早释放的内存。它可能为NULL。它可能指向数组的最后一个元素(标准明确允许的一个元素)。

指针的类型不会告诉编译器内存的整个布局。您可以定义一个字符串,然后定义指向起点中间,终点或终点之后的指针,所有这些都是具有相同类型的有效指针。 C ++中的基本指针的类型系统根本不够复杂,无法对这种信息进行编码,因为这不是该语言的设计方式。

const char * p = "James";  // valid pointer to the beginning of a string
const char * p1 = p + 1;   // pointer to 'a'
const char * p5 = p + 5;   // pointer to the null terminator (0) after 's'
const char * p6 = p + 6;   // pointer to the memory directly after the terminator

最后,您提供的代码中包含一个 cast ,它使您可以进行所需的几乎任何转换,而无需编译器进行大量检查。因此,当编译器允许您将一件事投射到另一件事时,您应该不会感到惊讶。

答案 1 :(得分:0)

  

我的想法是编译器将为一个分配内存...

     

如果我尝试在其中放置多个字符。

实际上,您什么都没放。这不是将保留“ YELLOW SUBMARINE”的新“字符串”的创建。您只是指向存储在静态内存中的字符串的开头。