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

Weird behavior when assigning one char array to another char array using char

本文关键字:字符 数组 另一个 分配 char 使用 一个      更新时间:2023-10-16

当我尝试将一个元素从 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之间的内容都会更改。

char b[5];

这里,b是一个5数组,未初始化chars.在初始化它们之前检查它们的值会导致未定义的行为

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

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

std::cout<<b;

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

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

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

调用char *流运算符,该运算符通过扫描字符串来确定字符串的长度,直到找到空字符。由于数组不包含空字符,因此它会一直读取数组的末尾,直到碰巧在其他地方找到空字符。在您的情况下,看起来您的编译器在堆栈中存储了ba,因此它会打印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), '');
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;
}