首页 > 解决方案 > 在声明中初始化时,字符数组上 cout 的奇怪输出?仅当我在此之后声明另一个数组时才会发生

问题描述

带有输出的极其简单的代码我不明白......

#include  <iostream>

using namespace std;

int main() {

    char text1[] = {'v', 'e', 'r', 'y'};
    cout << text1 <<  endl;
    char text2[] = "strange";
    cout << text2 << endl;

    return 0;
}

出于某种原因,我得到了这个输出:

very�&gt;��

奇怪的

每次输出为“非常”时,后跟第二个数组中相同数量的字符。如果我将第一行更改为

char text1[] = "very";

或者如果我不声明并计算第二个数组。

必须与使用 {'', '', '', ...} 初始化 char 的方式有关。我注意到在这种情况下 sizeof(text1) 是 4 并且在使用 char text1[ ] = "非常"; sizeof(text1) 为 5,最后一个位置留空。声明第二个字符时,第一个字符 sizeof 仍然准确,但是第二个字符位于内存中第一个字符之后的位置。

如果我像这样重写程序......

int main() {

    char text1[] = {'v', 'e', 'r', 'y'};
    char text2[] = "strange";
    cout << text1 <<  endl;
    cout << text2 << endl;

    return 0;
}

输出变为:

verystrange

strange

似乎如果我声明更多的 char 数组,它总是在第一个(text1 [])之后滑入最后一个,并且它会在内存中向前碰撞其他的以腾出空间。它只发生在使用 {}; 初始化。真的只是想知道这里发生了什么......我看不出这会在编写良好的程序中引起任何问题。

标签: c++arrayscharoutputcout

解决方案


总结评论中的响应,在 C 中,“字符串”没有关联的长度。相反,它由一个尾随空字符表示的“字符串”的结尾,即0.

当您使用初始化字符数组时

char text1[] = {'v', 'e', 'r', 'y'};

您创建了一个精确的四个字符的数组,没有尾随的空值。如果您尝试将此“字符串”传递给需要尾随空分隔字符串的函数,例如std::cout::operator<<(const char*),您将产生未定义的行为,因为将读取字符串之后的任意内存,直到找到空字符。

在评论中的示例中,仅使用一个数组时不打印垃圾的唯一原因是数组后面的内存恰好是0s (也许是因为您正在使用调试标志进行编译?)。但是,当您使用两个数组时,第二个数组在堆栈内存中的第一个数组之后,因此cout::operator<<无法分辨第一个数组的结束位置和第二个数组的开始位置。


推荐阅读