是否可以从 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++ 内存池:这种分配和释放方法是不是正确?

互操作 C++ 时释放分配的内存

我是不是必须在 Opencv C 包装器中为 C++ 接口释放 New 分配的内存

在 C++ 中删除其类的实例后,分配给 cpp 中定义的全局静态变量的内存是不是被释放?

如何从 c++ 的方面(方面 c++)释放或删除函数中的分配对象?

alloca() 可以替代 C++ 中的自动指针吗?