我的C ++代码,将字符串推送到mystack
#include <iostream>
#include <stack>
#include "NativeLogger.h"
std::stack<std::string> mystack;
JNIEXPORT void JNICALL
Java_NativeLogger_push(JNIEnv *env, jobject obj,jstring name)
{
std::string s = env->GetStringUTFChars(name, 0);
mystack.push(s);
return;
}
JNIEXPORT void JNICALL
Java_NativeLogger_pop(JNIEnv *env, jobject obj)
{
mystack.pop();
return;
}
我在使用Java运行时收到了崩溃报告,知道如何解决吗?
Java运行时环境检测到致命错误:
SIGSEGV(0xb)在pc = 0x00007f29421a0207,pid = 18007, tid = 0x00007f2942d3e700
JRE版本:Java(TM)SE运行时环境(8.0_144-b01)(内部版本 1.8.0_144-b01)Java VM:Java HotSpot(TM)64位服务器VM(25.144-b01混合模式linux-amd64压缩的oops)问题框架:C [libc.so.6 + 0x97207] __libc_malloc + 0x197
答案 0 :(得分:1)
GetStringUTFChars
返回指向实际字符串的副本的指针的可能性很低,您可以通过将其直接作为参数传递给std::string
的构造函数来立即将其丢弃,从而导致内存泄漏。
您需要挂起指针才能释放指针:
const char *p = env->GetStringUTFChars(name, NULL);
std::string s(p);
env->ReleaseStringUTFChars(name, p);
请注意,即使在极少数情况下没有进行任何复制,您仍然需要调用ReleaseStringUTFChars
,因为VM可能会将Java字符串固定在内存中,这可能会干扰垃圾收集器。
答案 1 :(得分:1)
Java代码:
package recipeNo025;
public class HelloWorld {
public static native void pushString(String s);
public static native String popString();
static {
System.loadLibrary("HelloWorld");
}
public static void main(String[] args) {
HelloWorld.pushString("Hello");
System.out.println(HelloWorld.popString());
}
}
C ++代码
#include <iostream>
#include <stack>
#include "jni.h"
#include "recipeNo025_HelloWorld.h"
std::stack<std::string> mystack;
JNIEXPORT void JNICALL Java_recipeNo025_HelloWorld_pushString
(JNIEnv *env, jclass obj, jstring str) {
// we have to get string bytes into C string
const char *c_str;
c_str = env->GetStringUTFChars(str, NULL);
if(c_str == NULL) {
return;
}
std::cout << "Passed string: " << c_str << std::endl;
std::string my_string(c_str);
mystack.push(my_string);
// after using it, remember to release the memory
env->ReleaseStringUTFChars(str, c_str);
}
JNIEXPORT jstring JNICALL Java_recipeNo025_HelloWorld_popString
(JNIEnv *env, jclass obj) {
std::string s = mystack.top();
mystack.pop();
return env->NewStringUTF(s.c_str());
}
执行:
> java -Djava.library.path=:./lib -cp target recipeNo025.HelloWorld
Passed string: Hello
Hello
此外,我还考虑过使用Singleton模式,而不是使用用于堆栈的全局变量。