Swapnil
Swapnil

Reputation: 2051

The address of the pointer changes when passed to a C function below the JNI layer

I am trying to write native C code in Android using NDK. I have a function segment_offline() which takes in many arguments including an integer pointer int * num_segments. I want this pointer because I want to read the value assigned to the the integer this pointer is pointing to in my C function which acts as my JNI interface. Here is the code for segment_offline():

int * segment_offline(const SEGMENT_DATATYPE *x, const int num_samples_x, const float *svara_cents, const int *svara_lengths, const int num_svaras, const int type, const int hop_size, const float tonic, int *num_segments) {

int i;

// using DTW ...
if (0 == type) {

    filtered_samples_t fns;

    // removing the negative frequencies in Hz.
    filter_negative_samples(x, num_samples_x, &fns);

    __android_log_print(ANDROID_LOG_DEBUG, "LogNDK", "After filter_negative_samples\n");

    // converting the Hz to Cents
    convert_pitch_to_cents(fns.arr_filtered, fns.len, tonic);

    __android_log_print(ANDROID_LOG_DEBUG, "LogNDK", "After convert_pitch_to_cents\n");

    //print_double_array(fns.arr_filtered, fns.len);
    segments_t seg = segment_offline_dtw(fns.arr_filtered, fns.len, svara_cents, svara_lengths, num_svaras, hop_size);

    __android_log_print(ANDROID_LOG_DEBUG, "LogNDK", "After segment_offline_dtw\n");

    int * ret_segments = (int *) malloc(sizeof(seg.num_segments));

    __android_log_print(ANDROID_LOG_DEBUG, "LogNDK", "After allocating memory to ret_segments\n");

    // setting the value of the number of segments in the pointer that would be referred.
    // ########## I get a segmentation fault here #########
    __android_log_print(ANDROID_LOG_DEBUG, "LogNDK", "The number of segments are: %d\n", seg.num_segments);
    *num_segments = seg.num_segments;

    __android_log_print(ANDROID_LOG_DEBUG, "LogNDK", "After assigning the number of segments: %d\n", *num_segments);

    for (i = 0;i < seg.num_segments * 2; i++) {
        ret_segments[i] = fns.original_indices[seg.segments_pos[i]];
        printf("%d, ", ret_segments[i]);
    }
    printf("\n");

    __android_log_print(ANDROID_LOG_DEBUG, "LogNDK", "Returning from segment_offline\n");

    return ret_segments;
}

The JNI C function that I have written is:

JNIEXPORT jintArray JNICALL Java_com_camut_audioiolib_dsp_DSPAlgorithms_segmentOffline
  (JNIEnv *env, jclass cls, jdoubleArray x, jint numSamples, jfloatArray svaraCents,
  jintArray svaraLengths, jint numSvaras, jint type, jint hopSize, jfloat tonic) {

    jdouble *xDouble = (*env)->GetDoubleArrayElements(env, x, NULL);
    jfloat *svaraCentsFloat = (*env)->GetFloatArrayElements(env, svaraCents, NULL);
    jint *svaraLengthsInt = (*env)->GetIntArrayElements(env, svaraLengths, NULL);

    __android_log_print(ANDROID_LOG_DEBUG, "LogNDK", "The size of the type tonic is: %d", sizeof(tonic));

    int num_segments;

    int * segments = (int *) segment_offline(xDouble, numSamples, svaraCentsFloat, svaraLengthsInt,
        numSvaras, type, hopSize, tonic, &num_segments);

    if (NULL == segments) {
       return NULL;
    }

    // releasing the allocated memories ...
    (*env)->ReleaseDoubleArrayElements(env, x, xDouble, JNI_ABORT);
    (*env)->ReleaseFloatArrayElements(env, svaraCents, svaraCentsFloat, JNI_ABORT);
    (*env)->ReleaseIntArrayElements(env, svaraLengths, svaraLengthsInt, JNI_ABORT);

     return NULL;

  }

You see in the above code that I have initialized the num_segments as an int variable and passing the address of this variable to the function mentioned above.

So, it seems that I am unable to derefer the int pointer. Any suggestions on this. I need this pointer because I am returning other value as my function return value.

Upvotes: 3

Views: 782

Answers (1)

Sergio
Sergio

Reputation: 8209

Just a guess. Someone corrupts your num_segments before derefer. Try print its value immediately at function begin and then before crash line. Also crash log shows that SIGSEGV occurs on address 0x60000000, that is unlikely an address of stack object.

EDIT

Also incorrect argument value may be caused by call to incorrectly declared function, i.e. if you have call to function that is not defined yet or defined in another translation unit - you must provide forward declaration that tells to compiler about actual argument list and return type. Note that C89 allows implicit function declaration. In case if you don't declare the function - compiler supposes that it has int return type and takes any number of any arguments. See here for details. Note, that mismatch of definition and call signatures causes undefined behavior.

P.S. Also absence of forward declaration may force you to cast function return since compiler expects it to be int.

Upvotes: 2

Related Questions