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

如何在IntelliJ IDEA中通过Java运行C++ .exe文件并避免abort异常?

问题分析与解决方案

核心原因

  1. 工作目录不匹配:
    单独运行exe时,程序的工作目录是exe所在的Debug文件夹;但通过IntelliJ IDEA的Desktop.open调用时,exe的工作目录会变成IDEA项目的根目录(如C:\Users\LENOVO\IdeaProjects\sudoku)。即使toCPP.txt存在于exe同目录,此时程序也找不到该文件,导致后续读取到无效的Nhn值,用垃圾值分配数组时触发abort异常。

  2. C++代码健壮性不足:

    • 未检查文件是否成功打开,读取失败后直接使用未初始化的变量;
    • 异常捕获范围过窄,仅捕获double类型异常,内存分配失败、IO错误等致命问题无法被拦截;
    • 手动内存分配后未释放,存在内存泄漏风险。

解决方案

方案1:修正Java调用时的工作目录

放弃Desktop.open,改用ProcessBuilder指定exe的工作目录为其所在文件夹,确保程序能找到依赖文件:

package com.maxwonderf;

import java.io.File;
import java.io.IOException;

public class checkingCPP {
    public static void main(String[] args) throws IOException {
        File exeFile = new File("C:\\Users\\LENOVO\\IdeaProjects\\sudoku\\result\\Debug\\result.exe");
        ProcessBuilder pb = new ProcessBuilder(exeFile.getAbsolutePath());
        // 设置工作目录为exe所在文件夹
        pb.directory(exeFile.getParentFile());
        // 重定向输出到IDEA控制台,方便调试
        pb.inheritIO();
        pb.start();
    }
}

方案2:增强C++代码的错误检查

修改C++代码,增加关键步骤的有效性验证,避免无效操作触发abort:

#define _USE_MATH_DEFINES

#include <fstream> 
#include <iostream>
#include <cstring> 
#include <complex> 
#include <stdexcept>
#include <vector>
#include <math.h>
using namespace std;
using namespace complex_literals;

int main() {

    try {
        ifstream fin("toCPP.txt");
        // 检查文件是否成功打开
        if (!fin.is_open()) {
            cerr << "错误:无法打开toCPP.txt" << endl;
            system("pause");
            return 1;
        }

        int Nhn, fd, len;
        // 验证Nhn读取有效性
        if (!(fin >> Nhn) || Nhn <= 0) {
            cerr << "错误:Nhn读取失败或值无效" << endl;
            fin.close();
            system("pause");
            return 1;
        }

        // 用vector代替手动动态数组,避免内存泄漏
        vector<string> hhn(Nhn);
        for (int i = 0; i < Nhn; ++i) {
            if (!(fin >> hhn[i])) {
                cerr << "错误:读取hhn[" << i << "]失败" << endl;
                fin.close();
                system("pause");
                return 1;
            }
        }

        // 验证fd读取有效性
        if (!(fin >> fd) || fd <= 0) {
            cerr << "错误:fd读取失败或值无效" << endl;
            fin.close();
            system("pause");
            return 1;
        }

        // 验证len读取有效性
        if (!(fin >> len) || len <= 0) {
            cerr << "错误:len读取失败或值无效" << endl;
            fin.close();
            system("pause");
            return 1;
        }
        fin.close();

        cout << "Nhn = " << Nhn << endl;
        cout << "hhn = ";
        for (const auto& s : hhn) {
            cout << s << " ";
        }
        cout << endl;
        cout << "fd = " << fd << endl;
        cout << "len = " << len << endl << endl;

        auto j = 1.i;
        double Td = 1.0 / fd; // 用除法替代pow,更高效且避免潜在问题
        vector<double> Hhn(len);
        complex<double> tmp = 0. + 0.i;

        ofstream fout("result.txt");
        if (!fout.is_open()) {
            cerr << "错误:无法创建result.txt" << endl;
            system("pause");
            return 1;
        }

        for (int f = 0; f < len; f++) {
            Hhn[f] = 0;
            tmp = 0. + 0.i;
            for (int k = 0; k < Nhn - 1; k++) {
                char* endptr;
                double val = strtod(hhn[k].c_str(), &endptr);
                // 验证字符串转数字是否成功
                if (endptr == hhn[k].c_str()) {
                    cerr << "错误:hhn[" << k << "]不是有效数字" << endl;
                    fout.close();
                    system("pause");
                    return 1;
                }
                tmp += val * exp(-j * (2 * M_PI * k * Td * f));
            }
            Hhn[f] = abs(tmp);
            if (f + 1 < len) fout << Hhn[f] << ", ";
            else fout << Hhn[f];
            cout << endl << "Hhn[" << f << "] = " << Hhn[f] << endl;
        }
        fout << endl << len;
        fout.close();
    }
    catch (const exception& e) { // 捕获所有标准异常
        cerr << "错误:" << e.what() << endl;
    }
    catch (...) { // 捕获未知异常
        cerr << "错误:发生未知异常" << endl;
    }

    system("pause");
    return 0;
}

额外调试建议

可以在C++代码中添加当前工作目录输出,确认路径是否正确:

#include <direct.h> // 需要包含头文件
// ...
char cwd[1024];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
    cout << "当前工作目录: " << cwd << endl;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:02:48