【问题标题】:c++ Segmentation fault when trying to reverse print an arrayc++ 尝试反向打印数组时出现分段错误
【发布时间】:2018-04-14 19:18:50
【问题描述】:

我有一个由 [1,2,3,4,5,.,..] 之类的字符组成的数组,并且我有一个看起来像

的循环
  for (size_t i = 0; i < size; ++i)
    os << data[i]; // os is std::ostream&

此循环以正确的顺序打印数组,没有任何错误。但是当我使用这个循环向后打印时

  for (size_t i = (size - 1); i >= 0; --i)
    os << data[i];

我收到分段错误错误。为什么会发生这种情况?

【问题讨论】:

  • 如您所知,size_t 是一个无符号值。你能想到任何负的无符号值吗?
  • 不幸的是,我无法控制类型。有没有其他方法可以使它起作用?
  • 我会为 i 使用 int 类型,但如果你不能。然后我猜你可以在 os 之后使用一次 break 语句 i = 0
  • 当然有一种方法可以使用size_t 使其工作。您只需要了解size_t 不能为负数,并相应地调整您的逻辑。您可以使用 do-while 循环,使用后递减运算符完成比较,或者仍然使用 for 循环,但比较 &gt; 0,并在循环开始时递减,而不是在结束时递减。

标签: c++ arrays segmentation-fault


【解决方案1】:

条件i &gt;= 0 始终为真(因为size_t 是无符号类型)。你写了一个无限循环。

你的编译器不会警告你吗?我知道g++ -Wextra 在这里。

您可以这样做:

for (size_t i = size; i--; ) {
    os << data[i];
}

这使用后减量来检查i 的旧值,这允许循环在i = 0 之后停止(此时i 已经绕到SIZE_MAX)。

【讨论】:

  • 我按照这里的说明进行操作:stackoverflow.com/questions/30834885/…
  • 不幸的是它没有给出任何警告。
  • 这些说明的哪一部分建议您使用size_t
  • @SarahHyland 你用的是什么编译器?
  • G++ C++11,它启用了 -Wall 和 -Wextra。
【解决方案2】:

size_t 是无符号整数,所以它总是保持正数,所以你的循环是一个无限循环

【讨论】:

    【解决方案3】:

    您可以使用 C++ for-in 循环来避免该问题。示例:

    #include <iostream>
    #include <vector>
    #include <boost/range/adaptor/reversed.hpp>
    
    using std::vector;
    using std::cout;
    using boost::adaptors::reverse;
    
    int main()
    {
      auto v = vector<char>{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'X' };
    
      char const* sep = "";
      for (auto c : v)
      {
        cout << sep << c;
        sep = " ";
      }
      cout << "\n";
    
      sep = "";
      for (auto c : reverse(v))
      {
        cout << sep << c;
        sep = " ";
      }
      cout << "\n";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-01
      • 2019-09-13
      • 2016-09-01
      • 1970-01-01
      • 2013-11-10
      • 2020-04-21
      • 2020-08-15
      • 1970-01-01
      相关资源
      最近更新 更多