2011-06-04 3 views
31

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が解放すると言う人もいますし、VMが解放しないと言うと、それを解放するために奇妙なブードゥーの魔法を行うべきです。よくわかりません。

+0

[JNIメモリリークを回避するメモリを解放する]の可能な複製(http://stackoverflow.com/questions/1533378/jni-freeing-memory-to-avoid-memory-leak) – NPE

答えて

61

NewStringUTF()からconst char*引数のストレージは、完全にあなたの責任です:あなたはmalloc()testを割り当てた場合、その後、あなたはそれをfree()する必要があります。だから、あなたが投稿したスニペットは正しいです。あなたは別の場所でヒープを破壊しています。

矛盾する意見があります。一部の人は私が 自分自身を解放すべきだと言う人もいますし、一部の人はVM が解放されていると言いますが、VMはフリーでないと言う人もいます。 奇妙なブードー 魔法を解放してください。よくわかりません。

これらは、NewStringUTF()によって返されたjstringインスタンスについてのものです。それは'local references'の混乱する規則に従います。

この参照を終了した時点で、この参照をDeleteLocalRef()で公開することは決して誤りではありません。しかし、JVMスレッドのコンテキストでNewStringUTF()を呼び出すと、JVMは怪しげな魔法を実行します。ネイティブメソッドがJavaに戻ると、リークされたローカル参照は自動的にクリーンアップされます。したがって、最終的な呼び出し元がJavaスレッド内にあることが確実であれば、安全に参照をリークできます。

一方、ネイティブスレッドのコンテキストで実行している場合(Javaへのコールバックを行うイベント報告スレッドなど)、Javaへの復帰はありませんので、DeleteLocalRef()に電話する必要があります。jstring実際には、典型的なJNI呼び出しによって返される他のすべてのローカル参照)。

+1

Interersting。私は今どこに行くのか分かります。私はより永続的なjstringが必要です。ガベージコレクターの一員となり、一度掃除されると、私は本当に終わってしまいます。 – Martin

+1

'NewStringUTF()'で得られた 'jstring'で' DeleteLocalRef() 'を呼び出すのが安全でない/間違っている状況がありますか? – namuol

+0

@namuol jstringを後でjavaに渡す場合は、今すぐ削除しないでください。 –

4

あなたはDeleteLocalRef()が必要です.NewStringUTF()は、JVM上のmallocメモリで、JVMがメモリを管理します。

関連する問題