【问题标题】:Char array returns four times more data than expectedChar 数组返回的数据是预期的四倍
【发布时间】:2019-05-31 01:48:28
【问题描述】:

在我继续之前,代码如下:

#include <iostream>
using namespace std;

int main() {
    char array[] = {'a','b','c'};
    cout << array << endl;

    return 0;
}

我的系统:

  • VisualStudio 2019,默认 C++ 设置
  • 使用调试版本而不是发布版本

当我运行此代码示例时,我的控制台输出中会出现类似的内容:

abcXXXXXXXXX

那些 X 代表看似随机的字符。我知道它们来自该地址内存中的现有值,但我不明白为什么我从数组中返回 12 个字节而不是三个字节。

现在,我知道如果我使用 4 个字节长的整数来执行此操作,也许这会有意义,但 sizeof(array) 返回三个(即三个字节长,我知道 sizeof(array) / sizeof(array[0] 技巧。)当我确实尝试过使用整数,我更加困惑,因为我得到了一些四字节的十六进制数字(可能是内存地址?)

这可能是一个微不足道的问题,对不起,但我只是想弄清楚它为什么会这样。请不要使用向量,我在这里尽量保持非 STL。

【问题讨论】:

  • 在打印为字符串时,应使用 null 终止字符数组。
  • 我知道 nullbytes 是如何工作的,但这并没有改变只有三个字节的事实。如果编译器非常关心我在创建变量时声明了一个大小,为什么它不会在到达软缓冲区末尾时停止读取?
  • 试试这个:cout &lt;&lt; array[0] &lt;&lt; array[1] &lt;&lt; array[2] &lt;&lt; endl;
  • @Akira 虽然确实存在已知大小的数组,但当您将数组传递给cout 时,数组衰减char* 指针,即然后期望是一个以空结尾的 C 样式字符串。还要记住,C++ 提供了保护,防止越界读取数组,当你这样做时可能会发生奇怪的事情。

标签: c++ arrays


【解决方案1】:

cout 采用此 char 数组并将其作为以空字符结尾的字符串进行寻址。

由于此数组中的终止字符不是空字符(即char(0)),它会尝试打印直到遇到空字符。

此时,它会尝试读取您已分配的数组之外的内存,从技术上讲,任何事情都可能发生。

例如,每次调用函数时,该内存中可能有不同的数据,或者内存访问操作甚至可能是非法的,这取决于在调用函数时分配 array 的地址。

因此,您的程序的行为通常被认为是未定义的(或不确定的)。

【讨论】:

  • 请注意,undefined 是比非确定性条件更强的条件。例如,可以有一些程序随机产生不同的整数序列,而不是未定义的。
  • @M.M:我相信在有限状态机上,不存在真正的随机这样的东西,也就是说,即使rand()的行为也可以预测,如果一个人知道初始种子(更一般地说,当一个人知道机器上每个晶体管的当前状态时)。所以我认为这里的non-deterministic其实相当于大多数人通常所说的undefined
  • “未定义”是标准定义的一个术语,表示该行为根本没有被标准定义。例如,可以通过调用硬件真随机性发生器来实现真随机性。 (当然,您可以在 C++ 中执行此操作,假设生成器可供用户代码调用)
  • @goodvibration 有限状态机不是图灵完备的,因此通常无法运行 C++。你是说图灵机吗?
  • @M.M:嗯,我想这更像是一个理论上的论点,但我在前面评论中的观点仍然存在 - 如果硬件具有有限数量的状态,那么可以预测随机生成器的输出,因此它的行为是确定性的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多