C++项目exe模式下运行一点事都没有,结果打包成DLL,用Java调用Dll时就出错了,而且不是每次都出错,所以立刻判断很可能时是C++代码导致出现了内存泄漏的情况。(至于为什么C++项目exe模式下运行没问题,我也不知道,有没有大佬教教我)
一、报错代码
下面是Java调用Dlll的主要代码,由于不是每一次调用DLL都会报错,所以我循环了100次,确保能出现报错。
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import java.io.FileInputStream;
public class TestDll {
public static void main(String[] args) throws Exception {
String dxf = DXFUtil.dxfRead(new FileInputStream("D:\\WSKH\\Software\\WeChat\\WeChatFiles\\WeChat Files\\wxid_995kojs3kdj022\\FileStorage\\File\\2023-03\\1.txt"));
for (int i = 0; i < 100; i++) {
long s = System.currentTimeMillis();
Pointer pointer = new Memory(1024L * 1024L);
MyDll.mydll.parseDXFStringToMapPath2(dxf, pointer);
System.out.println(pointer.getString(0));
System.out.println("用时: " + (System.currentTimeMillis() - s) + " ms");
}
}
}
二、报错信息
运行的结果就是,程序异常退出,下面是异常退出的错误码。
Process finished with exit code -1073740940 (0xC0000374)
三、报错原因
分析原因,应该是C++代码出现了内存泄漏,一些new的对象没有得到及时的释放
于是我找到了那段代码,如下所示:
double product = product2D(new double[]{lastPoint.x - arcItor->centerpoint.x, -(lastPoint.y - arcItor->centerpoint.y)},
new double[]{curPoint->x - arcItor->centerpoint.x, -(curPoint->y - arcItor->centerpoint.y)});
我感觉可能是这样写,new 的 double[] 没有得到释放,于是改成了下面这样:
double* d1 = new double[]{lastPoint.x - arcItor->centerpoint.x, -(lastPoint.y - arcItor->centerpoint.y)};
double* d2 = new double[]{curPoint->x - arcItor->centerpoint.x, -(curPoint->y - arcItor->centerpoint.y)};
double product = product2D(d1,d2);
// 手动释放内存(数组的释放用delete[])
delete[] d1;
delete[] d2;
结果还是报错。。。后来抱着试一试的心态试了一下另一种写法,结果就可以了!具体代码请看解决方案
四、解决方案
double product = product2D(new double[2]{lastPoint.x - arcItor->centerpoint.x, -(lastPoint.y - arcItor->centerpoint.y)},
new double[2]{curPoint->x - arcItor->centerpoint.x, -(curPoint->y - arcItor->centerpoint.y)});
if (totalAngle > PI){
product = -product;
}
没错,就是在 new double[]
的时候加上长度2就可以了,原理应该是下面这样: