【问题标题】:Segmentation fault when reading a vector读取向量时出现分段错误
【发布时间】:2010-12-17 22:52:04
【问题描述】:

在c++程序中,当我想读取一个大小为2697806的向量时,总是得到Segmentation fault错误。 我已经尝试了所有可能的阅读方式:

void AUROC(vector<float> v) {
   ...
   for(std::vector<int>::size_type i = 0; i != v.size(); i++)
      if (v[i]>0) ++pos; else ++neg;

   for(std::vector<long>::size_type i = 0; i != v.size(); i++)
     if (v[i]>0) ++pos; else ++neg;

   for (vector<float>::iterator i=v.begin(); i!=v.end(); ++i)
     if (*i>0) ++pos; else ++neg;

   for (long i=0;i<=v.size();i++)
     if (v[i]>0) ++pos; else ++neg;

   for(int i=0;i<=v.size();i++)
     if (v[i]>0) ++pos; else ++neg;
}

...
int main(void) { 
    vector<float> scores;
    // put data in scores;
    AUROC(scores);
}

这个问题永远不会发生在尺寸小得多的向量上。

感谢您的帮助。 最好的, 佩加

【问题讨论】:

  • 请显示您在v中添加内容的代码。
  • "在一个 c 程序中,当我想读取一个向量时"太棒了,C 现在有向量了! =D
  • vector 分数; score.push_back((1==1 ) ? s : (-s));
  • 我将 score 的结果发送到另一个函数 void AUROC(vector v) 以这种方式:AUROC(scores);
  • 不要通过值传递,而是通过引用或指针传递

标签: c++ stl


【解决方案1】:

我知道您已经接受了答案,但您发布的代码存在以下循环问题:

for(int i=0;i<=v.size();i++)

向量索引是从零开始的。如果向量大小为 5,则有效索引为 0..4。您的代码会尝试访问元素 0..5,这是一个错误的错误。我相信您对堆栈大小的“修复”只是掩盖了其他实际问题。

此外,您应该通过引用而不是值来传递向量。当您调用AUROC(vector&lt;float&gt; v) 时,您当前正在复制向量。这是缓慢的,而且是对内存的极大浪费。把函数改成AUROC(vector&lt;float&gt; &amp;v)

【讨论】:

  • 非常感谢您的检查。在主要代码中它是: for(std::vector::size_type i = 0; i != v.size(); i++) 根据您所说的,这是正确的。我也将其更改为 AUROC(vector &v)。再次感谢。
【解决方案2】:

当你调用你的函数时:

vector<float> scores;
// put data in scores;
AUROC(scores);

scores 向量将被复制到堆栈中。您不应该通过堆栈传递如此大的数据集合(12 MBytes),将代码更改为引用或指针传递。

此外,您可以检查和更改主机上的堆栈限制。在 unix 上:

ulimit -s 

将打印stacklimit的当前设置。您可以通过

进行更改
ulimit -s size_in_kb

修改后检查

【讨论】:

  • 谢谢,它通过更改 Unix 中的堆栈大小来工作。干杯。佩加
  • 向量在堆栈上的使用不应超过 12-24 个字节,无论其大小如何。
  • @Chris Hopman,STL 可以有多种实现。这也是 INT 的向量或 FLOAT 的向量。此外,更改允许的堆栈大小有助于主题启动,您如何解释这一点?
  • @Chris Hopman,好的。似乎,线程开启者引用了错误的部分来源。
【解决方案3】:

由于它适用于较小的尺寸,我最好的猜测是您的堆栈空间不足。如何检查堆栈空间并更改它取决于您的操作系统:在 Linux 上运行 ulimit -s 进行检查并运行 ulimit -s SIZE 进行设置。

延伸阅读:http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/

【讨论】:

  • @Pegah,你需要让你的ulimit -s 大几十倍。例如。 ulimit -s 70000000。并通过ulimit -s 命令查看
  • 感谢您的回答。它是一个网络。我不能把它改成超过这个数量。现在它甚至不允许我将其更改为 2900000! bash: ulimit: stack size: cannot modify limit: this function is not allowed.
  • 所以如果你不能让你的堆栈大于 3 MB,就不要在你的堆栈上放 30 MB 的数据...
  • 只需要一个向量&就像你一开始就应该做的那样。
  • 被复制的向量使用的堆栈空间量不应取决于向量的大小...向量不会将其元素存储在堆栈中。我很确定问题出在被剪掉的代码中。
【解决方案4】:

这个:

for (long i=0;i<=v.size;i++)

应该是:

for (long i=0;i<=v.size();i++)

和其他地方类似。

【讨论】:

    【解决方案5】:

    我想知道你是否会弄乱堆栈。

    包装一下

    if (v[i]&gt;0) ++pos; else ++neg;

    在花括号中。

    { if (v[i]&gt;0) ++pos; else ++neg; }

    【讨论】:

    • 嗨,你说的包装是什么意思?
    • 这里的卷曲一定是无操作的,不是吗?
    • for(std::vector::size_type i = 0; i != v.size(); i++) {if (v[i]>0) ++pos; else ++neg;} 同样的错误。
    猜你喜欢
    • 2019-03-27
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    相关资源
    最近更新 更多