【问题标题】:Why was the stack around char array was corrupted为什么 char 数组周围的堆栈已损坏
【发布时间】:2014-12-11 05:27:09
【问题描述】:

我是来自 Java 的 C++ 新手。我正在努力从 Char 数组中提取第一个单词,所以我认为创建一个新数组来保存所有第一个单词字符并将它们传输到循环运行到句子中的空格是可行的。代码如下:

void execute(){
//start with getting the first word
char first_word[20];
int i = 0;
while (input[i] != ' '){ // input is a char array declared and modified with cin, obtaining the command.
    first_word[i] = input[i];
    i++;
}
print(first_word + ' ' + 'h' + ' ' + 'h' + 'a');
}

尝试执行此操作时,我收到错误“围绕变量 'first_word' 的堆栈已损坏”。为什么会这样?

【问题讨论】:

  • 输入从何而来?大概有20多个字符。我不明白你的打印功能。数组上的 + 不会连接字符串。如果你想要像 Java 这样简单的字符串,你应该使用std::string
  • first_word + ' ' 不会像您认为的那样做。 first_word 是一个字符数组,而不是字符串。
  • @NeilKirk 输入来自另一种方法,该方法简单地采用“cin >> input”,然后将它们全部小写。我不知道这是否是正确的做事方式。
  • std::string first_word(input, std::find(input, input + input_size, ' '); print(first_word + " h ha");
  • cin >> input 无效,如果 input 是一个字符数组(好吧,它是有效的,但它不会像你认为的那样做)。将input 改为std::string,但随后您必须重新编写execute() 才能使用std::string

标签: c++ arrays char stack


【解决方案1】:

input 是一个字符数组时,cin >> input 不会像你想象的那样做。 >> 运算符无法读入字符数组,您必须改用 cin.getline()cin.read()。因此,您实际上是通过处理无效内存来导致未定义的行为。

即使它确实有效,您也没有进行任何边界检查。如果input 在遇到空格字符之前有超过 20 个字符(或者更糟糕的是,根本不包含空格字符),您会将first_word 的末尾写入周围的内存中。

如果您真的想用 C++ 编写代码,请不要将字符数组用于字符串。这就是 C 处理字符串的方式。 C++ 使用 std::string 代替,它具有 find()substr() 方法等。而std::cin 知道如何使用std::string

例如:

#include <string>

void execute()
{
    //start with getting the first word
    std::string first_word;
    std::string::size_type i = input.find(' '); // input is a std::string read with cin, obtaining the command.
    if (i != std::string::npos)
        first_word = input.substr(0, i);
    else
        first_word = input;
    std::cout << first_word << " h ha";
}

【讨论】:

  • 当“输入”是“测试输入”时,我仍然会收到错误消息,那里甚至没有 20 个字符。那为什么?
  • cin &gt;&gt; input 不会像您认为的那样做。 cin &gt;&gt; 无法读入字符数组,请改用 cin.getline()cin.read()。所以你实际上是在处理无效的内存并导致未定义的行为。
  • 另外,即使它正常工作,您也不会在复制到 first_word 的字符末尾添加空终止符。正如马特所说,您的 printf() 语句没有按照您的想法执行(但这不会导致堆栈损坏,只会导致垃圾输出)。还有,
猜你喜欢
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 2012-11-08
  • 2019-09-04
  • 2020-07-26
相关资源
最近更新 更多