Reputation: 241
I am working on a research project to build a library which provides image processing tools. I need it to be wrapped from C++ to other languages.
I am currently working on the Java implementation using Jni (Java Native Interface).
My C++ core is built with a singleton pattern. Java calls C++ to get a pointer to the singleton.
static Kernel *getInstance()
{
if (!m_kernel)
m_kernel = new Kernel;
return m_kernel;
}
C++ returns the pointer as a long value.
JNIEXPORT jlong JNICALL Java_JavaCore_openKernelInstance(JNIEnv *, jobject)
{
Kernel* kernel=Kernel::getInstance();
std::cout << "pointer value at open" << kernel << std::endl;
return long(kernel);
}
Java provides this value in every method that requires access to this object, to tell C++ where the object is located (It no longer holds the pointer).
Result
pointer address hex 10x7f0a440e3a20
pointer adress dec 139682068183584
id session1=0
id session2=1
Everything works fine except for the end of the "session". When Java asks C++ to close its work and delete its objects, here is what happends
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
Segmentation fault (core dumped)
There is an infinite loop where it tries to delete the pointer. Here is the destructor
Kernel::~Kernel(){
std::cout << "pointer delete" << m_kernel << std::endl;
delete m_kernel;
}
The java code
public static void main(String[] args){
JavaCore jc = new JavaCore();
long l = jc.openKernelInstance();
int idSession = jc.openSession(l);
int idSession2 = jc.openSession(l);
System.out.println("pointer dec="+l);
System.out.println("id session1="+idSession);
System.out.println("id session2="+idSession2);
jc.closeKernelInstance(l);
}
Upvotes: 0
Views: 531
Reputation: 9716
This happens because you delete m_kernel
object recursively in the destructor. Every time you call delete m_kernel
you call the same destructor. You should not delete m_kernel
in the destructor, it's enough to call delete
once on the object: something like this.
void closeKernelInstance() {
delete m_kernel;
}
And destructor should be empty in this case:
Kernel::~Kernel(){
}
By the way, you could consider using Meyer's singleton, in this case your singleton will be destroyed automatically on exit:
static Kernel & getInstance()
{
static Kernel theInstance;
return theInstance;
}
Upvotes: 4