是否可以从 C++ 释放分配的内存输出
Posted
技术标签:
【中文标题】是否可以从 C++ 释放分配的内存输出【英文标题】:is it possible to free allocated memory output from C++ 【发布时间】:2016-02-06 08:55:21 【问题描述】:我想知道是否可以从 C++ 中释放返回值。我在 C++ 中使用 NDK 来构建一个 android 本机库。
我想做这样的事情:
在我的 C++ 代码中:
JNI 入口点
JNIEXPORT jbyteArray JNICALL Java_myMethod(JNIEnv * env, jobject obj)
int len = 16;
char* buf = (char*) malloc(len);
jbyteArray array = env->NewByteArray (len);
env->SetByteArrayRegion (array, 0, len, reinterpret_cast<jbyte*>(buf));
std::thread&MyClass::asynchronousFree, this, array.detach();
return array;
还有一个异步调用的方法来释放返回值
void Myclass::asynchronousFree(jbytearray array)
//code to free the memory after a specified time
在我的 Android 代码中:
void process()
byte[] array = ndk.myMethod();
//do some stuff with the array
//here i need array erased from memory
感谢您的帮助。
【问题讨论】:
你是说释放buf
吗?如果是这样,您可以在SetByteArrayRegion
之后立即执行此操作,因为SetByteArrayRegion
将复制数据。
感谢您的回复。我不是在谈论释放 buf。我说的是释放 java 数组变量,它是 C++ jbytearray 数组变量的 JNI 代理。我想释放 Java 数组变量。
好吧,NewByteArray
创建了一个对 Java byte[]
的本地引用。当当前线程与 VM 分离或本机代码返回 Java 代码时,该本地引用将自动删除 IIRC。此时,如果没有其他人持有对 Java 对象的引用,则该对象将成为垃圾回收的候选对象。就像 Alex Cohn 所说的那样,您可以在数组被收集之前用垃圾覆盖它,但是您需要一种知道何时使用数组完成 process
的方法。
我可以假设我不想在 100 毫秒等一段时间后删除数组。在我的上下文中,我假设如果该过程未在这段时间内完成,则它是一种攻击。我真的需要这个敏感变量在内存中存在一段时间
【参考方案1】:
在 C++ 中执行此操作与在 Java 中执行此操作没有什么不同。这意味着,给定对数组或任何其他 Java 对象的引用,您不能强制该对象不存在,但您可以更改其属性。
对于数组,它的长度是不可变的,但元素不是。您的 asynchronousFree()
方法可以将所有元素设置为 0,否则表明该数组不再有效。
为了更好地控制情况,您可以使用任何您喜欢的 Java 容器,包括最接近数组功能的 ArrayList 或 ByteBuffer。
所有此类对象都支持这个或那个 clear()、reset() 或 resize(0) 方法,这些方法基本上会释放元素。与 Java 中的往常一样,其他一些代码可能仍保留对任何元素的引用。更糟糕的是,对于您提出的任何数据结构,总有一种方法可以执行“深度复制”并保留您想要销毁的值。
【讨论】:
我明白你的意思。然而,这是一个安全问题。我不想不信任 Java 代码,因为它更容易进行逆向工程和篡改。我不想擦除 NDK 返回的 java 字节数组 出于安全考虑,我看不出将数组的所有元素设置为垃圾和丢弃数组之间的区别。我不明白您可以通过这种方式实现什么样的防篡改,因为即使您销毁 asynchronousFree() 中的所有内容,Java 使用者也可以将内容复制到一个持久数组中,而该数组不是由您的图书馆控制。 是的,我明白了。即使我找到了删除 java 字节数组的方法,我也无法控制返回的 NDK 值的副本。 重要的是要了解在这种情况下没有任何特定于 JNI 的内容。所有可以做的事情,都可以在纯 Java 中完成。任何在纯 Java 中无法完成的事情都不会成为可能,因为它来自本机库。以上是关于是否可以从 C++ 释放分配的内存输出的主要内容,如果未能解决你的问题,请参考以下文章
共享内存实现上的 C++ 内存池:这种分配和释放方法是不是正确?
我是不是必须在 Opencv C 包装器中为 C++ 接口释放 New 分配的内存
在 C++ 中删除其类的实例后,分配给 cpp 中定义的全局静态变量的内存是不是被释放?