【问题标题】:Segmentation fault: 11; range-based for loop分段错误:11;基于范围的for循环
【发布时间】:2013-09-14 14:17:28
【问题描述】:

我正在使用 C++ 进行小型编程练习。目标是用 2 的前 32 个指数初始化一个数组,然后输出它们。 使用普通的 for 循环没有问题,但我尝试使用 C++11 标准中引入的基于范围的 for 循环。 在编译期间,我收到警告“基于范围的 for 循环是 C++11 扩展 [-Wc++11-extensions]”。 运行程序我得到错误“分段错误:11”,没有任何进一步的输出。

我已经知道 elem 变量以某种方式被破坏了,但我不知道如何。 希望你能帮助一个n00b :)

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    const int LAENGE = 32;
    long potenzen[LAENGE];

    for(int elem : potenzen)
    {
        potenzen[elem] = pow(2.0, (double) (elem + 1));
    }

    for(int elem : potenzen)
    {
        cout << endl;
        cout << potenzen[elem];
    }

    cout << endl;

    return 0;
}

【问题讨论】:

  • 从你使用foreach循环的方式来看,我猜你已经习惯了写javascript了:)
  • 哈哈,我希望!我对编程完全陌生,只是想尝试新的 C++ 标准:)

标签: c++ c++11 segmentation-fault


【解决方案1】:

elem 被分配了potenzen 中的,而不是索引。 cout &lt;&lt; elem; 是您想要打印数组元素的内容。为了填充数组,只需使用整数索引:

for (int i = 0; i < LENGTH; i++) { // ProTip #1: use English identifiers
    array[i] = 2 << i; // ProTip #2: don't use `pow()` when working with integers
}

关于编译器警告:编译时使用-std=c++11-std=c++0x 标志告诉编译器您打算使用C++11 功能(假设您使用GCC 或clang——我不确定其他编译器。)

【讨论】:

  • 看着这个从 4 或 5 个答案减少到只有两个很有趣。无论如何,+1 以解决所有问题!
  • @Cornstalks 是的...一些答案最初是错误的,其中一些已被修复,其中一些已被删除。还是谢谢!
  • 太棒了,感谢您的帮助!使用正常循环,我之前可以正常工作,但我认为学习/使用新标准也可能有用:) 仍然接受 Nemanja 的答案,只是因为你已经拥有如此高的声誉,但当然你的也同样有帮助:P
  • 嘿,我还有一个后续问题:这个
  • @Zuup &lt;&lt; 运算符重载。对于整数类型,a &lt;&lt; b 表示“a 向左移动了b 二进制位”,即。 e. a * 2 to the bth power。然而,标准流类会覆盖它,因此它充当流附加运算符,即。 e. std::cout &lt;&lt; foofoo 写入标准输出。
【解决方案2】:

Ranged for 循环会给你元素值,而不是元素索引。

    potenzen[elem] = pow(2.0, (double) (elem + 1));

应该是

for(int i = 0; i < LAENGE; i++)
  potenzen[i] = 2 << i;

(关于转移,请参阅H2CO3的答案和下面的他的cmets)

请注意,您不能在此处使用 foreach 循环:

for(int& elem : potenzen)
{
    elem = pow(2.0, (double) (elem + 1));
}

当您访问语句右侧的 elem 的未初始化值时。

还有:

for(int elem : potenzen)
{
    cout << endl;
    cout << potenzen[elem];
}

应该是

for(int elem : potenzen)
{
    cout << endl;
    cout << elem;
}

elem 将包含数组值。

【讨论】:

  • @H2CO3 因为他只想得到 2^(i+1) 的整数?
  • 没错。而pow()doubles 上运行,我们知道,浮点运算并不精确,因此它们不可靠。也许他会得到序列1 3 7 15等......
  • 另外,应该是2 &lt;&lt; i1 &lt;&lt; (i + 1),但肯定不是2 &lt;&lt; (i + 1)。如果他想要pow(4, i),前者将是解决方案。
  • 现在你的答案很完美!
  • @Zuup 谢谢!但是,你真的应该接受 H2CO3 的回答,因为他帮了我很多,让这个答案变得有价值!
【解决方案3】:

上面的答案正确地指出了代码中的问题,但是如果你想将数组索引作为元素值,你必须设置它们,否则它们将被初始化为不确定(垃圾)值;以下代码也是一个与您尝试做的有点相似的解决方案:

#include <iostream>
#include <algorithm>

int main()
{
  constexpr auto count = 32;
  unsigned long long values[count] = { }; // initialise elements to 0
  auto i = 0;
  // fill them with their respective index values
  std::generate_n(values, count, [&i] { return i++; });
  for(auto &x : values)
  {
    // without casting the literal 2 would be treated as an int
    x = static_cast<unsigned long long>(2) << x;
    std::cout << x << std::endl;
  }
  return 0;
}

我使用 unsigned long long 而不是 long,因为在许多系统上 long 的大小是 4 个字节,但 2^32 = 4294967296 = 0x100000000 即需要 33 位。此外,由于我们知道所有值都将是正数,因此将其设为无符号更有意义。

【讨论】:

    猜你喜欢
    • 2021-04-08
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    相关资源
    最近更新 更多