JNI and pointer deletion

Discussion in 'Java' started by Edsoncv, Apr 23, 2008.

  1. Edsoncv

    Edsoncv Guest

    Hello All
    Some time ago I did some modifications at a JNI function and I am
    facing some problems, so I need some tips hot to solve it.
    My java code calls a C++ code, that calls the java code again many
    times.
    In the first call to C++ from java, a C++ object is created (named
    "problem"), and passed to Java (casted as a jlong), in order to, in
    the next call to C++, retrieve the C++ object again.
    The "create" function is like that:
    Code:
    JNIEXPORT jlong JNICALL create
    (JNIEnv *env, jobject obj_this,
     jint n,  jint m,
     jint nele_jac, jint nele_hess,
     jint index_style, jboolean call_finalize_solution, jboolean
    call_intermediate_callback)
    {
    	/* create the IpoptProblem */
    	Jipopt* problem=new Jipopt(env, obj_this, n, m, nele_jac, nele_hess,
    index_style,
    		call_finalize_solution, call_intermediate_callback);
    	if(problem == NULL){
    		return 0;
    	}
    
    	// return our class
    	return (jlong)problem;
    }
    [\code]
    
    The communication between them is perfect, except for one fact, the
    destroy function that delete the pointer "problem"; inside C++ code
    lead to JVM crash. the delete function is like that:
    [code]
    JNIEXPORT void JNICALL destroy
      (JNIEnv *env,
     jobject obj_this,
      jlong pipopt){
         // cast back our class
           Jipopt *problem = (Jipopt *)pipopt;
    
           if(problem!=NULL){
              delete problem;
         }
      }
    [\code]
    But there is also an interesting  thing: if I call the destroy
    function this way, the crash does not happen:
    [code]
    JNIEXPORT void JNICALL destroy
      (JNIEnv *env,
      jobject obj_this,
      jlong pipopt){
         // cast back our class
           Jipopt *problem = (Jipopt *)pipopt;
    
           if(problem!=NULL){
              problem = NULL;
              delete problem;
         }
       }
    [\code]
    I mean, if I point the allocated pointer to NULL before its deletion,
    the crash does not occur, if I just delete it (like in the first
    code), the crash happens. I think that the possible source of this
    problem is the fact that the java code still holds it reference to
    jlong reference. Is it right? Pointing "problem" to NULL would not
    lead to memory leak if I call this function many times? Is this the
    right way to do this deletion? Is this deletion necessary or the JVM
    "takes care" of this deletion issue?
    
                          Bye
     
    Edsoncv, Apr 23, 2008
    #1
    1. Advertising

  2. On Wed, 23 Apr 2008 08:31:45 -0700 (PDT), Edsoncv wrote:
    > The communication between them is perfect, except for one fact, the
    > destroy function that delete the pointer "problem"; inside C++ code
    > lead to JVM crash.

    [...]
    > I mean, if I point the allocated pointer to NULL before its
    > deletion, the crash does not occur, if I just delete it (like in the
    > first code), the crash happens.


    Setting the pointer to NULL before calling delete means that you
    aren't actually deleting the object at all. "delete NULL" has no
    effect at all, so your object is still allocated. Do this enough times
    and you will run out of memory.

    If delete (when the pointer is not NULL) causes a crash, then there
    are three likely reasons:

    - the object has already been deleted. Deleting it a second time
    isn't allowed.

    - the pointer has changed (i.e. you have changed it) since it was
    allocated, so you are attempting to delete something "random" that
    was never allocated with new in the first place.

    - you've done something bad with a *different* pointer (such as a
    reference to a java object in one of your many calls to java from
    the c++ code) that has corrupted the metadata used by new and
    delete, and delete crashes as a result.

    > I think that the possible source of this problem is the fact that
    > the java code still holds it reference to jlong reference.


    That's true. You should clear the jlong pointer stored on the java
    side when you delete the object, or there is a risk that you attempt
    to use it again after deleting the object (or delete it a second
    time).

    /gordon

    --
     
    Gordon Beaton, Apr 23, 2008
    #2
    1. Advertising

  3. On Wed, 23 Apr 2008 08:31:45 -0700 (PDT), Edsoncv wrote:
    > Jipopt* problem=new Jipopt(env, obj_this, n, m, nele_jac, nele_hess,
    > index_style, call_finalize_solution, call_intermediate_callback);


    One thing that I missed in my previous response...

    You are passing a copy of "env" to the Jipopt constructor, and
    presumably use it to invoke JNI functions later. That's a really bad
    idea, and potentially violates an important JNI rule: the env pointer
    is only valid in the context it was created for. Violating that rule
    will almost guarantee a crash.

    See sections 10.14, 8.1.1 and 8.1.4 here:
    http://java.sun.com/docs/books/jni/html/jniTOC.html

    /gordon

    --
     
    Gordon Beaton, Apr 24, 2008
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alex Hunsley

    IBM's JNI fails where Sun's JNI works

    Alex Hunsley, Nov 3, 2003, in forum: Java
    Replies:
    4
    Views:
    882
    Alex Hunsley
    Nov 4, 2003
  2. Christopher Pisz

    safe deletion of pointer, trees

    Christopher Pisz, Sep 3, 2004, in forum: C++
    Replies:
    2
    Views:
    379
    John Harrison
    Sep 4, 2004
  3. Aff@n
    Replies:
    1
    Views:
    379
    Ian Collins
    Oct 16, 2006
  4. Marcus

    Pointer deletion question

    Marcus, Feb 16, 2007, in forum: C++
    Replies:
    4
    Views:
    320
    Marcus
    Feb 16, 2007
  5. Replies:
    5
    Views:
    4,991
    Stuart Redmann
    Aug 9, 2007
Loading...

Share This Page