NewStringUTF () и освобождение памяти - PullRequest
38 голосов
/ 04 июня 2011

Должен ли я освободить выделенную строку после ее передачи NewStringUTF()?

У меня есть код, подобный следующему:

char* test;
jstring j_test;

test = some_function(); // <- malloc()s the memory
j_test = (*env)->NewStringUTF(env, test);

free(test); // <- should this be here?

Когда я освобождаю строку после передачи ее NewStringUTF(), Я получаю signal 11 (SIGSEGV), fault addr deadbaad ошибку.Если я уберу вызов free(), ошибка исчезнет.Что я делаю не так?

Я вижу противоречивые мнения.Некоторые говорят, что я должен освободить его сам, некоторые говорят, что виртуальная машина освобождает его, некоторые говорят, что виртуальная машина не освобождает его, и вы должны сделать странную магию вуду, чтобы освободить его.Я в замешательстве.

Ответы [ 2 ]

70 голосов
/ 06 июня 2011

Хранение аргумента const char* для NewStringUTF() полностью является вашей ответственностью: если вы выделили test с malloc(), то вам нужно free(). Итак, размещенный вами фрагмент верен. Вы портите кучу где-то еще.

Я вижу противоречивые мнения. Некоторые говорят, что я должен освободить его сам, некоторые говорят, что ВМ освобождает это, некоторые говорят, что VM не освобождает это и вы должны сделать странное вуду магия, чтобы освободить его. Я в замешательстве.

Они говорят об экземпляре jstring, возвращаемом NewStringUTF(). Это следует за запутанными правилами для «локальных ссылок» .

Никогда не ошибочно выпускать эту ссылку с DeleteLocalRef(), когда вы закончите с ней. Однако JVM выполняет некоторую сомнительную магию, если вы вызываете NewStringUTF() в контексте потока JVM. Когда нативный метод возвращается в Java, любые утечки локальных ссылок автоматически очищаются. Поэтому, если вы уверены, что ваш конечный вызывающий абонент находится в потоке Java, вы можете спокойно утратить ссылку.

С другой стороны, если вы работаете в контексте собственного потока, скажем, какого-то потока сообщений о событиях, делающего обратные вызовы в Java, возврата в Java никогда не будет, поэтому вы должны сами вызвать DeleteLocalRef() на этом jstring (и в действительности все остальные локальные ссылки, возвращаемые типичными вызовами JNI).

5 голосов
/ 16 марта 2012

Вам просто нужен DeleteLocalRef (), NewStringUTF () - это просто память malloc на JVM, которую JVM позаботится о памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...