使用char将一个char数组分配给另一个char数组时的奇怪行为

时间:2019-08-05 16:46:24

标签: c++ arrays

当我尝试将一个元素从char数组复制到char然后从同一char复制到另一个char数组时,第二个char数组给出了奇怪的输出,通常包含第一个char数组中的整个字符串。仅当第二个char数组未初始化时,才会发生这种情况。我的问题是char如何将整个字符串传输到另一个char数组。

int main()
{
    char a[10] = "ababababa";
    char b[5];
    char temp;

    temp=a[1];
    b[0]=temp;

    std::cout<<b;

}

使用g ++时,我得到b{�Uarabababa 使用clang ++时,我得到b�U

每次运行程序时,bU之间的内容都会更改。

2 个答案:

答案 0 :(得分:1)

char b[5];

在这里,b5未初始化 char s的数组。在初始化它们之前检查它们的值会导致不确定的行为

temp=a[1];
b[0]=temp;

在这里,您 initialise 仅分配给b的第一个元素。其余的 still 尚未初始化。

std::cout<<b;

在这里,您将b用作数组,由于数组衰减,std::cout将其解释为c字符串(实际上,std::cout看到了const char*,默认情况下,假定为以空值结尾的c字符串)。由于它需要检查直到null终止符内部的所有元素的值,因此它会执行 undefined bahaviour (未定义行为),因为某些值未初始化。

调用未定义行为的程序无法预测其结果。从字面上看,任何事情都可能发生,包括在不同编译器上的不同行为,甚至在执行之间的不同行为。

答案 1 :(得分:0)

b中的字符未初始化,因此它们不太可能包含空字符。您将第一个字符初始化为'b',然后打印数组。

调用char *流运算符,该运算符通过扫描字符串来确定字符串的长度,直到找到空字符为止。由于数组不包含空字符,因此它将继续读取数组的末尾内容,直到碰巧在其他地方找到空字符为止。在您的情况下,看来您的编译器已将a存储在堆栈中的b之后,因此它会打印b的所有元素,以及其他一些字符(也许填充了b到内存中的偶数字节),然后a的内容,在a末尾的空终止符处停止。不能保证所有这些,并且会在编译器,操作系统甚至程序的不同运行之间改变。欢迎来到不确定行为的世界。

简单的解决方法是在程序开始时将b初始化为全零:

#include <algorithm>
#include <iostream>

int main()
{
    char a[10] = "ababababa";
    char b[5];
    std::fill(std::begin(b), std::end(b), '\0');
    char temp;

    temp=a[1];
    b[0]=temp;

    std::cout<<b;

}

或者用std::string完全避免问题:

#include <algorithm>
#include <iostream>

int main()
{
    std::string a = "ababababa";
    std::string b( 1, a[ 0 ] );

    std::cout<<b;

}
相关问题