【问题标题】:vector out of range/ range check矢量超出范围/范围检查
【发布时间】:2013-02-26 10:20:22
【问题描述】:

这里是新用户。 我一直在编写这段代码,它创建一个带有节点的网络,并使用一个随机数在它们之间创建边。我将整个图作为一个向量来跟踪,每个条目都是一个向量,表示一个节点,其元素是它的邻居。然后它使用深度优先搜索来查找组件的数量,这些组件是图形的独立部分(我的计数变量)。然后我将节点和它连接到的邻居的数量输出到一个 txt 文件中。代码可以编译,但是命令提示符给我一个错误:

在抛出 'std::out_of_range' 的实例后调用终止 what(): 向量::_M_range_check

此应用程序已请求运行时以不寻常的方式终止它。 请联系支持...

那么...这是什么意思,我该如何解决?

另外,我需要跟踪每个组件中有多少个节点,有什么想法吗?

提前致谢,这是我的代码:

#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <vector>
using namespace std;

void gengraph(int v, float p, vector <vector <int> >& G);
void DFS(vector <vector <int> > G, int v, vector<int>& M);

int main()
{
    int a = 1000;
    float b = 0.004;
    vector <vector <int> > G;
    gengraph(a,b,G);
    vector <int> M (1000);
    int count = 0;
    int i;
    for (i = 0; i < a; i++)
    {
        if (M[i]==0)
        {
            DFS(G, i, M);
            count += 1;
        }
    }
    ofstream myfile;
    myfile.open ("data.txt");
    for (int l=0; l<1000; l++)
    {
        myfile << "v   len(G[v])\n";
    }
    myfile.close();
}
void gengraph(int v, float p, vector <vector <int> >& G)
{
    for (int i = 0; i<1000; i++)
    {  
        for (int j = 0; j<1000; j++)
        {
            int y = rand();
            bool Prob = (y <= p);
            if (i == j)
                continue;
            else
            {
                if(Prob == true)
                {
                    G.at(i).push_back (j);
                    G.at(j).push_back (i);
                }
            }
        }
    }
}
void DFS(vector <vector <int> >& G, int v, vector<int>& M)
{
    M[v]=1;
    for(unsigned int j = 0; j < G[v].size(); j++)
    {
        if (M[j]==0)
        {
            DFS(G, j, M);
        }
    }
}

【问题讨论】:

    标签: c++ vector


    【解决方案1】:

    您创建了向量 > 但它的初始大小为 0。

    现在,当您使用 M.at() 访问它时,它会检查此索引是否超出范围,如果是这种情况则抛出异常。

    定义向量为:

    vector<vector<int> > M(1000);
    

    应该可以解决你的问题。

    您还应该使用 gdb 或其他调试器。它会让你的生活更轻松

    【讨论】:

    • 我尝试使用vector M(1000);但它给了我同样的错误。如何使 Codeblocks 上的调试器工作?
    • 如果您安装了 gdb,那么只需像这样运行您的程序:“gdb --args yourprogram your parameters”
    • 还打印您所做的每一步,以查看错误是如何发生的以及在哪个迭代中发生的。没有调试器也没有错误信息,很难得到错误
    【解决方案2】:
    vector <vector <int> > G;
    

    这会创建一个向量的整数向量,但最初没有整数向量元素。尽管如此,您调用G.at(i)... - 对于i 的任何值,都会立即访问一个不存在的元素。

    另外,rand() 返回一个随机的 32 位整数,因此几乎总是大于您的 0.004 float。你可能想使用(rand() % 1000000 / 1000000.0) 之类的东西。随机数子系统应该通过调用ala srand(time(NULL));来初始化

    更一般地说,您最好使用一些std::cerr &lt;&lt; "x is now " &lt;&lt; x &lt;&lt; '\n'; - 打印变量、矢量大小等 - 分散在您的代码中,这样您就可以看到它在做什么以及哪里出了问题。或者,看看您是否可以获得交互式调试器并逐行逐步执行您的代码。

    【讨论】:

    • 我将 M 和 G 的大小调整为 1000,但它没有解决我的错误。我也这么想,但 0.004 是我的教授给我使用的概率。他给了我 rand 代码,说 rand() 会在 0 到 1 之间随机选择一个浮点数。
    • 您可能想找一位新教授:请参阅linux.die.net/man/3/rand。调整大小可能没有解决所有问题,但它应该解决了其中一些问题 - 将问题移至具有类似问题的后续代码。如果您输入一些跟踪信息,例如std::cerr &lt;&lt; "gengraph returning\n";,您将能够看到最后打印的内容并找到仍然存在问题的确切行。
    【解决方案3】:

    这意味着您索引了一个超出其范围的向量。

    vector::at() 执行范围检查。所以这可能是因为你没有为G预先分配足够的元素。

    【讨论】:

      【解决方案4】:

      第一个错误:在函数 gengraph() 中你使用了空向量:

      G.at(i) ...
      G.at(j) ...
      

      是的,你调用了 push_back,但是你调用了 at() 返回的方法。但是 at() 不能返回任何值 i 和 j 因为你的向量是空的。一种解决方案将这一行放在 gengraph() 的开头

      G.resize( 1000 );
      

      第二条建议:尽可能避免使用幻数。输入如下内容:

      const int size = 1000; 
      

      在文件的开头并使用大小而不是幻数 1000。 尤其是这个:

      int a = 1000;
      float b = 0.004;
      vector <vector <int> > G;
      gengraph(a,b,G);
      vector <int> M (1000); // use a here and better call it something more meaningfulness than a
      int count = 0;
      int i;
      for (i = 0; i < a; i++) { // or use M.size() here or both
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-13
        • 2020-03-14
        • 1970-01-01
        • 2018-06-16
        • 1970-01-01
        • 2021-10-04
        相关资源
        最近更新 更多