title: Memory leak on JNI native code
body: <p>I have a piece of JNI native code. When we invoked this native method + run other requests, the jvm will crash. </p>
  
  <p>Most probably, there is memory leak in this piece of JNI native method ( c code).</p>
  
  <p>Any body can help detect the memory leak in the below code? </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include "fns_data.h"
  #include "fns_client.h"
  #include "sockRW.h"
  #include "/usr/local/include/jni.h"
  #include "JNIiSearchLib.h"
  #include "com_eds_wise_util_JNIiSearchLib.h"
  
  JNIEXPORT jstring JNICALL
  Java_com_eds_wise_util_JNIiSearchLib_jniFNSSearchClient (
      JNIEnv *env, jobject obj, jstring jip_addr, jint jport_number,
      jstring jfield, jstring jquery_str, jint jhitnum)
  {
      HitIds           *hit_list   = NULL;
      hitListPktStruct *hitPkt     = NULL;
      int               hit_number = 0;
      int               i          = 0;
      int               fnsErrno   = 0;
      char             *result_str = NULL;
      jstring          rslt_str   = NULL;
      const char          *cip_addr   = NULL;
      const char          *cquery_str = NULL;
      char              errbuf[1024];
  
      cip_addr   = (*env)-&gt;GetStringUTFChars(env, jip_addr, 0);
      if (cip_addr == NULL) {
          return ((* env)-&gt;NewStringUTF (env, "Error: Cannot get IP address."));
      }
  
      cquery_str = (*env)-&gt;GetStringUTFChars(env, jquery_str, 0);
      if (cquery_str == NULL) {
          (*env)-&gt;ReleaseStringUTFChars (env, jip_addr, cip_addr);
          //(*env)-&gt;DeleteLocalRef(env, cip_addr);
          return ((* env)-&gt;NewStringUTF (env, "Error: Cannot get query string."));
      }
      printf ("[Java_JNILib_jniFNSSearchClient] ipaddress[%s] portnumber[%d]"
              " querystr[%s]\n\n", cip_addr, jport_number, cquery_str);
  
      /* Search and get back the handler &amp; total hits
       */
      hit_list = fns_search_client0 ((char *)cip_addr, jport_number,
                                     "PN", (char *)cquery_str, &amp;hit_number);
      fnsErrno = fns_error_message();
      if (fnsErrno) {
          printf ("Error %d during fns_search_client0()\n", fnsErrno);
          sprintf (errbuf, "Error: fns_search_client0() returns %d.", fnsErrno);
  
          rslt_str = (* env)-&gt;NewStringUTF (env, errbuf);
  
          (*env)-&gt;ReleaseStringUTFChars (env, jip_addr, cip_addr);
          (*env)-&gt;ReleaseStringUTFChars (env, jquery_str, cquery_str);
          //(*env)-&gt;DeleteLocalRef(env, cip_addr);
          //(*env)-&gt;DeleteLocalRef(env, cquery_str);
  
          fflush(stdout);
          return (rslt_str);
      }
  
      /* Display total hits
       */
      printf ("Total hits = %d\n", hit_number);
  
      /* Use the handler as parameter to retrieve the actual result
       */
      if (hit_number &gt; 0) {
          fns_display_ids0 ((char *)cip_addr, jport_number, hit_list,
                            0, hit_number - 1, &amp;hitPkt);
          fnsErrno = fns_error_message();
          if (fnsErrno) {
              printf ("Error %d during fns_display_ids0()\n", fnsErrno);
              sprintf (errbuf, "Error: fns_display_ids0() returns %d.", fnsErrno);
              rslt_str = (* env)-&gt;NewStringUTF (env, errbuf);
  
              if (hit_list) {
                  FREE_STRING (hit_list);
              }
              (*env)-&gt;ReleaseStringUTFChars (env, jip_addr, cip_addr);
              (*env)-&gt;ReleaseStringUTFChars (env, jquery_str, cquery_str);
              //(*env)-&gt;DeleteLocalRef(env, cip_addr);
              //(*env)-&gt;DeleteLocalRef(env, cquery_str);
  
              fflush(stdout);
              return (rslt_str);
          }
      }
  
      /* Enumerate every item in the result list and display them.
       * The results are returned as a string to Java in the following manner:
       *
       * "[hitresult1|hitresult2|hitresult3|..|hitresultN]\0"
       *
       *     where hitresultN = 94-byte record
       *
       * [+string94+|+string94]+stringTerminator 
       */
      printf ("malloc[%d]\n", (hit_number * 95) + 3);
  
      result_str = malloc (((hit_number * 95)+3) * sizeof(char));
      if (result_str == NULL) {
          printf ("Out of memory, unable to malloc\n");
          rslt_str = (* env)-&gt;NewStringUTF (env, "Error: Out of memory, unable to malloc");
  
          if (hit_list) {
              FREE_STRING (hit_list);
          }
          if (hitPkt) {
              FREE_HITLIST_STRUCT (hitPkt);
          }
          (*env)-&gt;ReleaseStringUTFChars (env, jip_addr, cip_addr);
          (*env)-&gt;ReleaseStringUTFChars (env, jquery_str, cquery_str);
          //(*env)-&gt;DeleteLocalRef(env, cip_addr);
          //(*env)-&gt;DeleteLocalRef(env, cquery_str);
  
          fflush(stdout);
          return (rslt_str);
      }
  
      sprintf (result_str, "[");
      for (i = 0; i &lt; hit_number; i++) {
          strcat (result_str, hitPkt-&gt;docNameList[i]);
          if (i != (hit_number - 1)) {
              strcat (result_str, "|");
          }
      }
      strcat (result_str, "]");
  
      printf ("\n\nFNS search result:[From Library]\n");
      printf ("%s\n\n",result_str);
  
      /* free the handler
       */
      if (hit_list) {
          FREE_STRING (hit_list);
      }
  
      /* free the result lists
       */
      if (hitPkt) {
          FREE_HITLIST_STRUCT (hitPkt);
      }
  
      /* prepare stuff for Java
       */
      rslt_str = (* env)-&gt;NewStringUTF (env, result_str);
  
      /* free our memory
       */
      if (result_str) {
          free (result_str);
      }
      (*env)-&gt;ReleaseStringUTFChars (env, jip_addr, cip_addr);
      (*env)-&gt;ReleaseStringUTFChars (env, jquery_str, cquery_str);
      //(*env)-&gt;DeleteLocalRef(env, cip_addr);
      //(*env)-&gt;DeleteLocalRef(env, cquery_str);
  
      fflush(stdout);
      return (rslt_str);
  }
  </code></pre>