使用 vector<vector<int> > 成员实例化对象时的段错误

Posted

技术标签:

【中文标题】使用 vector<vector<int> > 成员实例化对象时的段错误【英文标题】:Segfault upon instantiation of object with vector<vector<int> > member 【发布时间】:2015-03-30 00:19:59 【问题描述】:

在Multidimensional arrays as class member with arbitrary bounds 中,有人建议我应该使用整数向量的向量来表示我的数组支持的图形对象中的动态二维数组。但是,每当我尝试运行我的代码时,都会遇到分段错误。 GDB 指向变量定义为arraygraph 类型的行;我想这意味着我在指定edges 的类型时做错了。这是类定义:

class arraygraph 
private:

public:
    void open(char *filename);
    bool exists(int nodeid);
    int node_count(void);
    int weight(int nodea, int nodeb);
    void print();
private:
    int count;
    vector <vector <int> > edges; //A vector of vectors! [Inception Noise]
;

该对象的所有方法都已定义(有趣的是如何使用尚未填写的原型进行编译...)。代码编译时没有错误或警告。为什么会出现段错误?

编辑:

这是一些反汇编程序的输出:

163       int main(int argc, char *argv[]) 
          main(int, char**):
00401c86:   lea 0x4(%esp),%ecx
00401c8a:   and $0xfffffff0,%esp
00401c8d:   pushl -0x4(%ecx)
00401c90:   push %ebp
00401c91:   mov %esp,%ebp
00401c93:   push %ebx
00401c94:   push %ecx
00401c95:   sub $0x20,%esp
00401c98:   mov %ecx,%ebx
00401c9a:   call 0x402350 <__main>
164         arraygraph thegraph;
00401c9f:   lea -0x18(%ebp),%eax  (this is where the problem occured according to GDB)
00401ca2:   mov %eax,%ecx
00401ca4:   call 0x403e90 <arraygraph::arraygraph()>

那么显然段错误发生在arraygraph 构造之前?我不知道该怎么做。

编辑:

main() 的整体是这样的:

int main(int argc, char *argv[]) 
    arraygraph thegraph;
    thegraph.open(argv[1]);
    return 0; //Added this after I noticed I'd omitted it - didn't fix anything

这里是arraygraph::open():

//Only call .open() once. A second call will leave the old graph's dessicated corpse around the edges of the new one.
void arraygraph::open(char *filename)
    int count;
    int x, y;
    tomgraph loader;

    loader.open(filename);

    count=loader.node_count();

    //delete edges;
    //edges = new vector <vector <int> >;

    for (x=1; x <= count; x++) 
        for (y=1; y <= count; y++) 
            int weight;
            if (loader.is_connected(x,y,&weight) || loader.is_connected(y,x,&weight)) 
                edges[x-1][y-1]=weight;
             else 
                edges[x-1][y-1]=0; //0 represents "no edge"
            
        
    

但根据反汇编程序,无论如何都不会调用它。

编辑:

完整代码here。嗯...我认为它说它有效?让我试试不同的机器...

编辑:

不。在完全独立的 Linux 机器上编译后出现类似的段错误。

编辑:

为了确认,我注释掉了对 thegraph.open() 的调用。没修好。

【问题讨论】:

你可能想要一个构造函数,你能提供错误发生的源代码吗?错误不一定是由声明引起的,可能是它周围的代码。 @AlejandroDíaz 构造函数究竟会做什么?它周围没有代码; arraygraph mygraphmain() 中的第一行。 它将确保对象处于定义状态(即计数为 0),ideone.com/U3pHyg 您的代码按原样工作,因此类定义不是问题。 你的实例化实际上是什么样子的? 能否提供一个完整的编译示例来说明问题。 【参考方案1】:

你永远不会 resize edgespush_back 到它。所以它的大小是0 并且做edges[x-1][y-1] 你超出了界限。在arraygraph::open 中的循环之前,您可能必须做这样的事情:

edges.resize(count, std::vector<int>(count));

【讨论】:

添加调整大小不会改变任何事情。正如 disasm 所示,open() 无论如何都不会被调用。 @Schilcote 有时您必须收起调试器并使用良好的旧眼睛。在使用[ ] 之前,您从未调整过数组的大小,因此您访问的是无效项目。如果问题不是open,则完全删除该功能并查看该程序是否确实有效。如果它不起作用,那么你有一个严重损坏的编译器或损坏的标准库。 @PaulMcKenzie 是的,结果注释掉了调用 did 停止了段错误。但不是我第一次尝试。显然 GDB 只是在随机指令上停止。我今天刚坐下来用python重写了整个东西。 :P

以上是关于使用 vector<vector<int> > 成员实例化对象时的段错误的主要内容,如果未能解决你的问题,请参考以下文章

C++ vector容器用法

vector实现去重

intersect for multiple vectors in R

最短路 vector不T

vector作为函数返回类型

mybatis的小坑 ### The error may exist in com/vector/dao/*Mapper.xml