Подтвердить что ты не робот

NewStringUTF() и освобождение памяти

Должен ли я освободить выделенную строку после передачи ее на 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(), ошибка исчезнет. Что я делаю неправильно?

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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