gpt4 book ai didi

c++ - std::string 构造函数如何处理固定大小的 char[]?

转载 作者:太空狗 更新时间:2023-10-29 19:47:37 28 4
gpt4 key购买 nike

char[] 中的实际字符序列可能小于最大大小时,字符串构造函数如何处理固定大小的 char[]

char foo[64];//can hold up to 64
char* bar = "0123456789"; //Much less than 64 chars, terminated with '\0'
strcpy(foo,bar); //Copy shorter into longer
std::string banz(foo);//Make a large string

在这个例子中,banz 对象字符串的大小是基于原始的 char* 长度还是它被复制到的 char[]?

最佳答案

首先,您必须记住(或知道)C++ 中的 char 字符串实际上称为 null-terminated 字节字符串null-terminated 位是一个特殊字符 ('\0'),它指示字符串的结尾。

您必须记住(或知道)的第二件事是数组自然会衰减为指向数组第一个元素的指针。对于示例中的 foo,当您使用 foo 时,编译器确实会执行 &foo[0]

最后,如果我们看一下this std::string constructor reference你会看到有一个重载(数字 5)接受 const CharT*(CharT 是普通 char char 字符串)。

把它们放在一起,用

std::string banz(foo);

您将指针传递给 foo 的第一个字符,std::string 构造函数会将其视为以 null 结尾的字节字符串。通过找到空终止符,它知道字符串的长度。数组的实际大小无关紧要,未使用。

如果你想设置 std::string 对象的大小,你需要通过传递一个长度参数(构造函数引用中的变体 4)来明确地做到这一点:

std::string banz(foo, sizeof foo);

这将忽略空终止符并将 banz 的长度设置为数组的大小。请注意,空终止符仍将存储在字符串中,因此将指针(由例如 c_str 函数检索)传递给需要空终止字符串的函数,那么该字符串将看起来很短。另请注意,空终止符之后的数据将未初始化 并且具有不确定 内容。您必须在使用该数据之前对其进行初始化,否则您将得到undefined behavior。 (在 C++ 中,甚至读取不确定的数据也是 UB)。


正如 MSalters 的评论中提到的,读取未初始化和不确定数据的 UB 也用于使用显式大小构造 banz 对象。它通常会工作并且不会导致任何问题,但它确实违反了 C++ 规范中规定的规则。

修复它很容易:

char foo[64] = { 0 };//can hold up to 64

上面的代码会将数组的所有初始化为零。以下 strcpy 调用将不会触及超出终止符的数组数据,因此数组的其余部分将被初始化。

关于c++ - std::string 构造函数如何处理固定大小的 char[]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52854079/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com