【发布时间】:2021-07-09 04:40:48
【问题描述】:
我一直在使用 JNI 编写的 Java 中的 C++ 库。
操作系统:Ubuntu 16.04
代码:
JNIEXPORT jint JNICALL Java_FocasUser_Focas2_getMacroDataArray
(JNIEnv *env, jobject instance, jint handle, jint startIndex, jint endIndex, jdoubleArray jArr) {
int len = env->GetArrayLength(jArr);
IODBMR *macro;
macro = (IODBMR *) malloc(8 + (8 * len));
clock_t before = clock();
if (PrintLogCat) LOGGER.debug("cnc_rdmacror.. start Index: [%d]\t endIndex:[%d]\t",1);
short ret = cnc_rdmacror(handle, startIndex, endIndex, 8 + (8 * len), macro);
int elapsedTime = calcElapsedTime(before, clock());
loggerStream << "[" << "cnc_rdmacror" << "]=" << ret << "\tElapsed Time ms : " << elapsedTime;
fileLogger(loggerStream.str(), LOG_FILE_WRITE_COND(elapsedTime));
loggerStream.str("");
jdouble *arr = env->GetDoubleArrayElements(jArr, 0);
double temp = 0;
if (ret == EW_OK) {
for (int idx = 0; idx <= endIndex - startIndex; idx++) {
temp = macro->data[idx].mcr_val;
for (int i = 0; i < macro->data[idx].dec_val; i++) {
temp = temp / 10;
}
arr[idx] = temp;
}
} else {
env->ReleaseDoubleArrayElements(jArr, arr, 0);
free(macro);
free(arr);
macro = NULL;
arr = NULL;
env->DeleteLocalRef(instance);
if (PrintLogCat) LOGGER.error("getMacroValue pmc error : %d", ret,1);
return -1;
}
env->ReleaseDoubleArrayElements(jArr, arr, 0);
free(macro);
free(arr);
arr = NULL;
macro = NULL;
env->DeleteLocalRef(instance);
return 0;
}
“双重释放或损坏”出现在“free(arr)”行。 我在“free(arr)”之前初始化然后没问题,但我不确定它是否正常。 我该如何解决?
非常感谢您,
日志:https://www.evernote.com/l/AtWkcucPzCZMN4b61B9rvNLCZazK95mk3Eo/
【问题讨论】:
-
通过使用
std::vector而不是malloc来摆脱手动内存管理。那么这些对free的调用都不需要在那里,把事情搞砸了。事实上,对于健全的 JNI 编程,最好使用 RAII 对象,例如std::vector,而不是手动管理内存。代码变得更简单、更易于维护,并且实际上消除了内存泄漏问题。 -
您已经使用
ReleaseDoubleArrayElements释放了arr指向的数组。是什么让您认为您也需要free?作为一般规则,如果您没有从malloc获得任何东西,您不应该free它(除非相关文档明确说明您应该这样做)。 -
您可以考虑(如果在 Linux 上)使用valgrind;用调试信息编译大部分代码,所以使用
g++ -Wall -Wextra -g -O
标签: c++ java-native-interface fatal-error