我正在玩c ++中的c字符串,并发现一些我不能理解的行为,当我没有终止char
数组时。
char strA[2] = {'a','\0'};
char strB[1] = {'b'};
cout << strA << strB;
我希望这会打印ab
,而是打印aba
。如果我在strB
之前声明strA
,它会按预期工作。有人可以解释一下这里发生了什么吗?
答案 0 :(得分:7)
这是未定义的行为,您很幸运,替换这两个数组的声明适合您。让我们看看您的代码中发生了什么:
char strA[2] = {'a','\0'};
创建一个可以像字符串一样处理的数组 - 它是 null终止。
char strB[1] = {'b'};
创建一个不能被视为字符串的数组,因为它缺少空终止字符'\0'
。
std::cout << strA << strB;
第一部分是<< strA
,效果很好。它打印a
,因为strA
被视为const char*
,作为std::ostream& operator <<
的参数提供将用于打印每个字符,直到 null终止字符为止遇到强>
那会怎么样?然后,<< strB
正在执行(实际上这里发生的事情有点不同,而且比简单地将这一行划分为两个单独的std::cout <<
调用更复杂,但这并不重要)。它也被视为const char*
,,预计将以提及的'\0'
结束,但不是......
这会导致什么?你很幸运,在内存中随机只有一个字符(再次 - 随机)'\0'
,这会停止(可能接近无限)的打印过程。
为什么,如果我在
strB
之前声明strA
,它会按预期工作?
那是因为你很幸运,编译器决定在strA
之后声明你的strB
,因此,当打印strB
时,它打印出它所包含的所有内容+打印strA
,以null终止字符结尾。这不保证。避免使用char[]
来表示和打印字符串。请改用std::string
,它会为您处理空终止字符。
答案 1 :(得分:0)
打印char数组时,C
(和C++
)约定是打印所有字节,直到&#39; \ 0&#39;。
由于局部变量的组织方式,strB
的内存落后于strA
,因此在打印strB
打印时只需&#39 ;溢出&#39;并继续打印strA
,直到终止&#39; \ 0&#39;。
我猜当减速度反转时,strB
的打印由0
终止,因为那里没有设置任何其他东西,但你不应该依赖它 - 这被称为垃圾值。
不要使用未终止的C字符串, 。一般来说,也要避免使用C字符串,您可以使用更安全,更有趣的C++
std::string
。
当我在我的计算机上运行此代码时,我在ab
到a
之间打印了一堆(正好七个)奇怪的字符,这可能是strA
之间的任何内容。 &#39;和strB
的记忆空间
当我反转声明时,我得到ab$%^&
$%^&
是一堆奇怪的字符 - strB
的内存到下一个随机{{1}之间的字符}}