You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Dijkstra函数后C++程序无输出,主函数执行异常求助

问题分析与解决方案

看起来你的程序遇到了栈溢出的问题,这也是调用dijkstra函数后无输出、主函数后续代码停止执行的核心原因。让我一步步拆解问题并给出修复方案:

1. 核心问题:结构体值传递导致栈溢出

你的mygragh结构体里包含了一个int map[1000][1000]的二维数组,这个数组大小是1000*1000*4 = 4,000,000字节(约4MB)。当你以值传递的方式把g传给dijkstra函数时,程序会在栈上完整拷贝这个4MB的数组。而大多数操作系统的默认栈空间只有1~8MB,这么大的拷贝直接撑爆了栈,导致程序异常终止——连dijkstra里的cout << "called dijkstra\n";都来不及执行,更别说主函数后续的代码了。

修复方案:改用引用传递

把dijkstra的函数参数改成引用,避免拷贝整个庞大的结构体:

void dijkstra(mygragh& g, int dis[], int pre[], int v0) {
    // 函数内容不变
}

这样只会传递结构体的地址,不会拷贝数组,彻底解决栈溢出问题。

2. 其他潜在问题与修复

除了核心的栈溢出,你的代码还有几个需要修正的地方,否则即使解决了栈溢出,程序也可能运行异常:

(1) 未包含INT_MAX的头文件

INT_MAX定义在<climits>头文件中,你的代码没有包含它,属于未定义行为,有些编译器可能会报错或出现奇怪的数值。在代码开头添加:

#include <climits>

(2) 非标准的变长数组

C标准并不支持int dis[n];这种变长数组(这是C99的特性,部分编译器如GCC会支持,但不是跨平台的)。改用vector来动态创建数组更符合C规范:

// 替换原来的int dis[n]; int pre[n];
vector<int> dis(n);
vector<int> pre(n);

同时建议把dijkstra函数的参数改成引用(比指针更安全):

void dijkstra(mygragh& g, vector<int>& dis, vector<int>& pre, int v0) {
    int n = g.n;
    vector<bool> visit(n, false);
    for (int i = 0; i < n; i++) {
        if (g.map[v0][i] != INT_MAX) {
            dis[i] = g.map[v0][i];
            pre[i] = v0;
        } else {
            dis[i] = INT_MAX;
            pre[i] = -1;
        }
    }
    // 后续代码不变
}

(3) 图初始化逻辑不一致

你注释掉了fill(g.map, g.map + n * n, INT_MAX);,改用了g.map[i][j] = 100;,但dijkstra函数里仍然判断g.map[v0][i] != INT_MAX,这会导致逻辑错误——因为你的边权值可能小于100,而初始化的100会被当成有效的边权,而不是“不可达”的标记。

恢复fill的代码(记得包含<algorithm>头文件,因为fill在里面),这样才能正确初始化所有边为“不可达”:

#include <algorithm> // 添加这个头文件

// 在初始化map的地方:
fill(g.map[0], g.map[0] + n * n, INT_MAX); // 二维数组首地址用g.map[0]更准确
for (int i = 0; i < n; i++) {
    g.map[i][i] = 0;
}

(4) 避免整数溢出

在dijkstra的松弛操作中,添加g.map[u][j] != INT_MAX的判断,防止dis[u] + g.map[u][j]溢出:

if (!visit[j] && g.map[u][j] != INT_MAX && dis[j] > dis[u] + g.map[u][j]) {
    dis[j] = dis[u] + g.map[u][j];
    pre[j] = u;
}

修复后的完整代码示例

整合所有修改后的代码如下:

#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;

struct mygragh {
    int map[1000][1000];
    int e;
    int n;
};

void dijkstra(mygragh& g, vector<int>& dis, vector<int>& pre, int v0) {
    cout << "called dijkstra\n";
    int n = g.n;
    vector<bool> visit(n, false);
    for (int i = 0; i < n; i++) {
        if (g.map[v0][i] != INT_MAX) {
            dis[i] = g.map[v0][i];
            pre[i] = v0;
        } else {
            dis[i] = INT_MAX;
            pre[i] = -1;
        }
    }
    visit[v0] = true;
    for (int i = 0; i < n; i++) {
        int min_val = INT_MAX, u = -1;
        for (int j = 0; j < n; j++) {
            if (!visit[j] && dis[j] < min_val) {
                min_val = dis[j];
                u = j;
            }
        }
        if (u == -1) {
            break;
        }
        visit[u] = true;
        for (int j = 0; j < n; j++) {
            if (!visit[j] && g.map[u][j] != INT_MAX && dis[j] > dis[u] + g.map[u][j]) {
                dis[j] = dis[u] + g.map[u][j];
                pre[j] = u;
            }
        }
    }
}

int main() {
    cout << "called main\n";
    mygragh g;
    int n = 5;
    int e = 7;
    g.n = n;
    g.e = e;
    vector<int> dis(n);
    vector<int> pre(n);

    // 初始化图为不可达
    fill(g.map[0], g.map[0] + n * n, INT_MAX);
    for (int i = 0; i < n; i++) {
        g.map[i][i] = 0;
    }

    cout << "请输入7条边的起点、终点和长度(节点编号0-4):\n";
    for (int i = 0; i < e; i++) {
        int c1, c2, l;
        if (!(cin >> c1 >> c2 >> l)) {
            cerr << "输入无效,程序退出\n";
            return 1;
        }
        // 确保节点编号合法
        if (c1 < 0 || c1 >= n || c2 < 0 || c2 >= n) {
            cerr << "节点编号超出范围\n";
            return 1;
        }
        g.map[c1][c2] = l;
        g.map[c2][c1] = l;
    }

    dijkstra(g, dis, pre, 0);
    cout << "节点0到节点1的最短路径长度:" << dis[1] << endl;

    return 0;
}

验证效果

现在运行程序,你会看到:

  1. 首先输出called main
  2. 提示输入边信息
  3. 输入完成后,输出called dijkstra
  4. 最后输出节点0到节点1的最短路径长度

这样就解决了你遇到的所有问题。

内容的提问来源于stack exchange,提问作者Sherry Le

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:27:46