【问题标题】:Segmentation Fault, program works fine分段错误,程序运行正常
【发布时间】:2014-07-09 13:25:58
【问题描述】:

我正在为最小生成树问题实施 Prim 算法。程序运行良好,我得到了所需的输出,但最后我收到了 Segmentation Fault。我检查了我的程序是否有错误,但程序很好。

这里是源代码

#include <iostream>
#include <cstdio>
#define INF 1000000
#define N 5

using namespace std;

class Graph
{
    int V;
    int adj[][N];

    public:
        Graph(int,int mat[][N]);
        void primsMST();
};

Graph::Graph(int v, int mat[][N])
{
   this->V = v;
   for(int i=0; i<v; i++)
   {
       for(int j=0; j<v; j++)
           adj[i][j] = mat[i][j];
   }
}

void Graph::primsMST()
{
    int i, j;

    int key[V];     // Key Value which is used to pick minimum weight vertex
    int parent[V];  // To store Tree
    bool mstSet[V];  // Mark Vertex included in MST

    // Initialize Key Values to infinite and mstSet to false
    for(i=0; i<V; i++)
    {
        key[i]=INF;
        mstSet[i] = false;
    }

    // Initialize initial vertex
    key[0] = 0;
    parent[0] = -1;

    int minm, min_i;
    for(int k=0; k<V-1; k++)
    {
        // Get min Key from all vertices
        minm = INF;
        for(i=0; i<V; i++) {
            if(!mstSet[i] && key[i]<minm)
            {
                minm = key[i];
                min_i = i;
            }
        }

        // Include min key vertex in MST
        mstSet[min_i] = true;

        // Update key values of vertices adjacent to min vertex
        for(j=0; j<V; j++)
        {
            if( adj[min_i][j] && !mstSet[j] && adj[min_i][j] < key[j])
            {
                key[j] = adj[min_i][j];
                parent[j] = min_i;
            }
        }
    }

    for(i=0; i<V; i++)
        cout<<i<<", "<<key[i]<<", "<<parent[i]<<endl;

    // Print Minimum spanning Tree
    cout<<"Edge\tWeight"<<endl;
    for(i=1; i<V; i++)
        cout<<i<<"--"<<parent[i]<<"\t"<<adj[i][parent[i]]<<endl;

    cout<<endl;
}

int main()
{

    int adjmat[][N] =  {{0, 2, 0, 6, 0},
                      {2, 0, 3, 8, 5},
                      {0, 3, 0, 0, 7},
                      {6, 8, 0, 0, 9},
                      {0, 5, 7, 9, 0},
                     };

    Graph g(N, adjmat);

    g.primsMST();

    cout<<endl;
    return 0;
}

程序使用gcc version 4.7.2 编译。 当我运行这个程序时,我得到了所需的图表输出,但最后出现了分段错误。

$ ./primsMST
0, 0, -1
1, 2, 0
2, 3, 1
3, 6, 0
4, 5, 1
Edge    Weight
1--0    2
2--1    3
3--0    6
4--1    5

Segmentation fault

这是使用 gdb 的调试输出

$ gdb primsMST
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/abhishek/myPrograms/geeksforgeeks/graphs/primsMST...done.
(gdb) set logging on
Copying output to gdb.txt.
(gdb) run
Starting program: /home/abhishek/myPrograms/geeksforgeeks/graphs/primsMST 
0, 0, -1
1, 2, 0
2, 3, 1
3, 6, 0
4, 5, 1
Edge    Weight
1--0    2
2--1    3
3--0    6
4--1    5



Program received signal SIGSEGV, Segmentation fault.
0x0000000000000002 in ?? ()
(gdb) backtrace
#0  0x0000000000000002 in ?? ()
#1  0x0000000800000003 in ?? ()
#2  0x0000000000000005 in ?? ()
#3  0x0000000000000003 in ?? ()
#4  0x0000000700000000 in ?? ()
#5  0x0000000800000006 in ?? ()
#6  0x0000000000000000 in ?? ()
(gdb) quit 

谁能解释我为什么会收到此错误?

【问题讨论】:

  • valgrind 可能很有用。
  • 我不知道如何使用valgrind。
  • 只需使用调试符号编译然后运行valgrind yourProgram。 Valgrind 会大量发出错误信号:p
  • 有趣的是,我看不出你在哪里将 adj 初始化为正确的尺寸。
  • @barakmanos adj 在构造函数Graph::Graph 中使用来自参数mat 的值进行初始化。如果没有初始化怎么输出是正确的?

标签: c++ gdb segmentation-fault


【解决方案1】:

您没有为图形类的“adj”矩阵成员的行分配内存。这是坠机最可能的原因。 这可能会有所帮助:This 可能会有所帮助。

我的理解是程序运行是偶然的/因为 adj 数组很小。

【讨论】:

  • 好的,我现在明白了,我从来没有指定 adjrow 维度造成了问题。但我认为我这样做是因为我在 2D 数组声明中读到 row 如果值在声明本身中初始化,则可以跳过维度。我接受这个作为答案。
【解决方案2】:

问题可能是由于对堆栈分配的数组(adjmat 和/或 Graph::adj)的错误访问造成的。由于这些数组是在堆栈上分配的,不正确的访问可能会损坏存储在那里的其他数据(如函数返回地址或其他变量),这可能会在调用析构函数或使用无效返回地址时导致分段错误。

【讨论】:

  • adj 矩阵 ara 的行数根本没有分配。只有指向行的指针的列数组在堆栈上。
  • 谢谢,现在有问题了。因为我没有在 adj 中声明 row 维度。很可能它覆盖了堆栈帧,因此发生了分段错误。
猜你喜欢
  • 2017-02-18
  • 1970-01-01
  • 2020-07-29
  • 2020-06-25
  • 2013-11-30
  • 2013-09-13
  • 1970-01-01
  • 2016-03-27
相关资源
最近更新 更多