繁体   English   中英

C++中的输入错误和分段错误

[英]Input error in C++ and segmentation fault

我有代码 gom.cpp

#include "another.cpp"
#include <iostream>
#include <vector>
#include <assert.h>

using namespace std;

typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
bool same[MAXV];
int s;
const int INF = 0;
#define rep(i,a,b) for (__typeof(a) i=(a); i<(b); ++i)


template <class T>
void assert_equal(T expected, T actual, bool kill = false) {
    if (!(expected == actual)) {
        cout << "Assertion failed:" << endl;
        cout << "Expected: " << expected << endl;
        cout << "  Actual: " << actual << endl;
        if (kill) assert(false);
    }
}


pair<vii, vvi> construct_gh_tree(flow_network &g) {
    int n = g.n;
    int v;
    vii par(n, ii(0, 0));
    vvi cap(n, vi(n, -1));
    rep(s,1,n) {
        int l = 0, r = 0;
        par[s].second = g.max_flow(s, par[s].first, false);
        memset(d, 0, n * sizeof(int));
        memset(same, 0, n * sizeof(int));
        d[q[r++] = s] = 1;
        while (l < r) {
            same[v = q[l++]] = true;
            for (int i = g.head[v]; i != -1; i = g.e[i].nxt)
                if (g.e[i].cap > 0 && d[g.e[i].v] == 0)
                    d[q[r++] = g.e[i].v] = 1;
        }
        rep(i,s+1,n)
            if (par[i].first == par[s].first && same[i]) par[i].first = s;
        g.reset();
    }
    rep(i,0,n) {
        int mn = INF, cur = i;
        while (true) {
            cap[cur][i] = mn;
            if (cur == 0) break;
            mn = min(mn, par[cur].second), cur = par[cur].first;
        }
    }
    return make_pair(par, cap);
}
int compute_max_flow(int s, int t, const pair<vii, vvi> &gh) {
    if (s == t) return 0;
    int cur = INF, at1 = s;
    while (gh.second[at1][t] == -1)
        cur = min(cur, gh.first[at1].second), at1 = gh.first[at1].first;
    return min(cur, gh.second[at1][t]);
}

void test() {
    int N,M,source,sink,cap;
    cout<<"Enter the vertices and edges";
    cin>>N>>M;


    flow_network g(N);
    pair<vii, vvi> gh;

cout<<"Now enter the edges and their capacity";
    for(int i=0; i < M; i++) {
            cin>>source;
            cin>>sink;
            cin>>cap;
        g.add_edge(source, sink, cap, cap);
        assert_equal(g.max_flow(source, sink), compute_max_flow(source, sink, gh));
    }
gh = construct_gh_tree(g);
for(int i = 0; i < N; ++i) {
    for(int j = 0; j < N; ++j) {
        assert_equal(g.max_flow(i, j), compute_max_flow(i, j, gh));
    }
}
}


int main()
{
    test();
    return 0;
}

另外,另一个.cpp

#include <iostream>
#include <vector>
#include <string.h>
#include <algorithm>

using namespace std;

#define MAXV 2000

int q[MAXV], d[MAXV];

struct flow_network {
    struct edge {
        int v, cap, nxt;
        edge() { }
        edge(int _v, int _cap, int _nxt) : v(_v), cap(_cap), nxt(_nxt) { }
    };
    int n, ecnt, ecnt1, *head, *curh;
    vector<edge> e, e_store;
    flow_network(int _n, int m = -1) : n(_n), ecnt(0) {
        e.reserve(2 * (m == -1 ? n : m));
        head = new int[n], curh = new int[n];
        memset(head, -1, n * sizeof(int));
    }
    void destroy() { delete[] head; delete[] curh; }

    void reset() { e = e_store; }

    void add_edge(int u, int v, int uv, int vu = 0) {
        e.push_back(edge(v, uv, head[u]));
        head[u] = ecnt++;
        e.push_back(edge(u, vu, head[v]));
        head[v] = ecnt++;
        //cout<<ecnt;
    }
    int augment(int v, int t, int f) {
        if (v == t) return f;
        for (int &i = curh[v], ret; i != -1; i = e[i].nxt)
            if (e[i].cap > 0 && d[e[i].v] + 1 == d[v])
                if ((ret = augment(e[i].v, t, min(f, e[i].cap))) > 0)
                    return (e[i].cap -= ret, e[i^1].cap += ret, ret);
        return 0;
    }
    int max_flow(int s, int t, bool res = true) {
        if(s == t) return 0;
        e_store = e;
        int f = 0, x, l, r;
        while (true) {
            memset(d, -1, n * sizeof(int));
            l = r = 0, d[q[r++] = t] = 0;
            while (l < r)
                for (int v = q[l++], i = head[v]; i != -1; i = e[i].nxt)
                    if (e[i^1].cap > 0 && d[e[i].v] == -1)
                        d[q[r++] = e[i].v] = d[v]+1;
            if (d[s] == -1) break;
            memcpy(curh, head, n * sizeof(int));
            while ((x = augment(s, t, 0)) != 0) f += x;
        }
        if (res) reset();
        return f;
    }
};

当我编译代码并运行它时,输入不会停止。 可能是什么错误? 基本上,我正在尝试编译 gom.cpp 文件,运行测试并最终显示结果。 另外,我无法显示结果。

输入如下:

6 8 -> vertices and edges
0 1 2 -> edge from 0-1 with capacity 2
and so on -> 8 edges present.

我在输入上遇到分段错误。

我在第一个提示中输入了“6 8”,在第二个提示中输入了“0 1 2”。 它在 max_flow() 中处于无限循环中。 特别是这条线

    if (d[s] == -1) break;

永不中断。 在我的示例中, s 是第二个提示的 0 输入。

这是分配 d[s] 的行:

    d[q[r++] = e[i].v] = d[v]+1;

我已经确定 d[0] 被分配了 1 并且永远不会改变。

您在这一行遇到分段错误gh.second[at1][t] in gom.cpp 因为 gh 从未初始化。

我想你的意思是把g.add_edge(source, sink, cap, cap); compute_max_flow(source, sink, gh)之前。

这里有一些提示可以帮助你...

  1. 您永远不应该包含 .cpp 文件。 仅包含 .h(header) 文件。 将声明放在头文件中,将定义放在 .cpp 中。
  2. 简单的 cout 语句可以告诉您发生分段错误的位置。
  3. 始终明确使用括号来标记代码块的开始和结束。

好的:

int x =1;
if(x==1)
{
  std::cout<<"x is 1"<<std::endl;
}
else
{
  std::cout<<"x is not 1"<<std::endl;
}

坏习惯:

int x=1;
if(x==1)
  std::cout<<"x is 1"<<std::endl;
else
  std::cout<<"x is not 1"<<std::endl;
  1. 使用 gdb 调试代码问题:

GDB是帮助您调试 c/c++ 程序问题的程序。 要在 gdb 中运行您的程序,只需键入gdb <your_program>

在 gdb 中运行这个程序我得到了一个 SIGSEGV:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004029a8 in std::vector<int, std::allocator<int> >::operator[](unsigned long) const ()
Missing separate debuginfos, use: debuginfo-install glibc-2.16-34.fc18.x86_64 libgcc-4.7.2-8.fc18.x86_64 libstdc++-4.7.2-8.fc18.x86_64
(gdb) bt
#0  0x00000000004029a8 in std::vector<int, std::allocator<int> >::operator[](unsigned long) const ()
#1  0x0000000000401488 in compute_max_flow(int, int, std::pair<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > const&) ()
#2  0x00000000004015bd in test() ()
#3  0x000000000040171f in main ()

为了进一步缩小分段错误发生的范围,我使用了简单的 cout 语句来定位确切的错误。

编辑:

改变

pair<vii, vvi> gh;

cout<<"Now enter the edges and their capacity";
    for(int i=0; i < M; i++) {
            cin>>source;
            cin>>sink;
            cin>>cap;
        g.add_edge(source, sink, cap, cap);
        assert_equal(g.max_flow(source, sink), compute_max_flow(source, sink, gh));
    }
gh = construct_gh_tree(g); 

    pair<vii, vvi> gh;

cout<<"Now enter the edges and their capacity";
    for(int i=0; i < M; i++) {
            cin>>source;
            cin>>sink;
            cin>>cap;
        g.add_edge(source, sink, cap, cap);
        gh = construct_gh_tree(g);
        assert_equal(g.max_flow(source, sink), compute_max_flow(source, sink, gh));
    }

但是,在此之后,您仍然需要处理max_flow中的无限循环......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM