如何在IntelliJ IDEA中通过Java运行C++ .exe文件并避免abort异常?
问题分析与解决方案
核心原因
工作目录不匹配:
单独运行exe时,程序的工作目录是exe所在的Debug文件夹;但通过IntelliJ IDEA的Desktop.open调用时,exe的工作目录会变成IDEA项目的根目录(如C:\Users\LENOVO\IdeaProjects\sudoku)。即使toCPP.txt存在于exe同目录,此时程序也找不到该文件,导致后续读取到无效的Nhn值,用垃圾值分配数组时触发abort异常。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
相关产品推荐
相关产品推荐

