繁体   English   中英

为什么可以将char char *分配给char *?

[英]Why is it possible to assign a const char* to a char*?

我知道例如"hello"const char*类型。 所以我的问题是:

  1. 我们如何将像"hello"这样的文字字符串分配给非const char*如下所示:

     char* s = "hello"; // "hello" is type of const char* and s is char* // and we know that conversion from const char* to // char* is invalid 
  2. 是一个像"hello"这样的文字字符串,它将在我的所有程序中占用内存,或者它就像临时变量在语句结束时会被销毁?

实际上, "hello"的类型为char const[6]

但问题的要点仍然是正确的 - 为什么C ++允许我们将只读内存位置分配给非const类型?

唯一的原因是向后兼容旧的C代码,它不知道const 如果C ++在这里一直很严格,它会破坏很多现有的代码。

也就是说,大多数编译器都可以配置为警告这些代码已弃用,甚至默认情况下这样做。 此外,C ++ 11完全不允许这样做,但编译器可能还没有强制执行它。


对于Standerdese粉丝:
[参考1] C ++ 03标准:§4.2/ 2

不是宽字符串文字的字符串文字(2.13.4)可以转换为“指向字符的指针”的右值; 可以将宽字符串文字转换为“指向wchar_t的指针”类型的右值。 在任何一种情况下,结果都是指向数组第一个元素的指针。 仅当存在明确的适当指针目标类型时才考虑此转换,而不是在通常需要从左值转换为右值时。 [ 注意:此转换已弃用 见附录D.]为了在重载决策(13.3.3.1.1)中进行排序,这种转换被认为是一个数组到指针的转换,然后是一个限定转换(4.4)。 [示例:“abc”转换为“指向const char的指针”作为数组到指针的转换,然后转换为“指向char的指针”作为限定转换。 ]

C ++ 11简单地删除了上面的引用,这意味着它是C ++ 11中的非法代码。

[参考2] C99标准6.4.5 / 5“字符串文字 - 语义”:

在转换阶段7中,将值为零的字节或代码附加到由字符串文字或文字产生的每个多字节字符序列。 然后使用多字节字符序列初始化静态存储持续时间和长度的数组,该数组足以包含序列。 对于字符串文字,数组元素的类型为char,并使用多字节字符序列的各个字节进行初始化; 对于宽字符串文字,数组元素的类型为wchar_t,并使用宽字符序列进行初始化...

如果这些数组的元素具有适当的值,则这些数组是否不同是未指定的。 如果程序试图修改此类数组,则行为未定义。

是像“hello”这样的文字字符串将在我的所有程序中占用内存所有它就像一个临时变量,当语句结束时它将被销毁。

它保存在程序数据中,因此可以在程序的生命周期内进行处理。 您可以从当前范围返回指针和对此数据的引用。

const char*强制转换为char*的唯一原因是与c的comatiblity,如winapi系统调用。 而这种演员阵容与其他任何常规演员都不同。

只需使用一个string

std::string s("hello");

这将是C ++的方式。 如果你真的必须使用char ,你需要创建一个数组并在其上复制内容。

第二个问题的答案是变量s作为类型指向char的类型存储在RAM中。 如果它是全局的或静态的,它将在堆上分配并在运行程序的生命周期内保留。 如果它是一个本地(“自动”)变量,它将在堆栈上分配并保持不变直到当前函数返回。 在任何一种情况下,它都占用了保持指针所需的内存量。

字符串"Hello"是一个常量,它作为程序本身的一部分与所有其他常量和初始化程序一起存储。 如果您构建程序以在设备上运行,则字符串将存储在ROM中。

请注意,因为字符串是常量而s是指针,所以不需要复制。 指针s只指向存储字符串的位置。

在您的示例中,您不是分配,而是构建。 例如, std::string(const char *)确实有一个std::string(const char *)构造函数(实际上它更复杂,但没关系)。 而且,类似地,char *(如果它是一个类型而不是指向一个类型的指针)可能有一个const char *构造函数,它正在复制内存。

我实际上并不知道编译器在这里是如何工作的,但我认为它可能与我上面描述的类似:在堆栈中构造"Hello"的副本,并使用此副本的地址初始化s

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM