Как освободить память, выделенную с помощью jShortArray/jByteArray, из JNI, Java и C++

Я пытаюсь освободить память t_data, которая назначается фиктивной переменной. (Код ниже). Теперь, как только я освобождаю t_data, программа выдает ошибку повреждения кучи, но вместо этого, если я копирую все содержимое из тела в новую память для t_data, все работает нормально. Код удаления вызывается где-то в другом методе класса (здесь не показан), он просто использует указатель t_Data для удаления памяти.

jshortArray val = (jshortArray)(m_pJVMInstance->m_pEnv->CallStaticObjectMethod(m_imageJ_cls, method_id, arr, (jint)t, (jint)c));
jsize len = m_pJVMInstance->m_pEnv->GetArrayLength(val);
jshort* body = m_pJVMInstance->m_pEnv->GetShortArrayElements(val, 0);       
unsigned short int* dummy = reinterpret_cast<unsigned short int*>(body);
//t_data = dummy; //NOTE: Once you free t_data later exception is thrown.
t_data = new unsigned short int[len];
for (int i = 0; i < len; i++) {
    unsigned short int test = *(body + i);
    *((unsigned short int*)t_data + i) = test;
}

Я пытаюсь найти способ, при котором мне не нужно запускать цикл for, чтобы скопировать данные тела в t_data и по-прежнему иметь возможность освобождать память. (Цикл for занимает слишком много времени для больших изображений.)


person Remaldeep    schedule 30.05.2018    source источник
comment
Ознакомьтесь с документацией, чтобы узнать, кто несет ответственность за удаление body. Я не гуру JNI, но вполне возможно, что сборщик мусора сделает это за вас. Не делайте delete вещей, если вы не выделили их или в документации API не указано, что вы несете ответственность за их удаление. Предпочитаю не выделять его в первую очередь.   -  person user4581301    schedule 31.05.2018
comment
Беглый взгляд на тему показывает, что память массива заблокирована до тех пор, пока вы не вызовете ReleaseShortArrayElements. Опять же, посмотрите подробности на соответствующей странице документации.   -  person user4581301    schedule 31.05.2018
comment
Дай Бог, чтобы кто-то, кто действительно разбирается в этом, мог зайти и дать реальный ответ. Если нет, посмотрите, можете ли вы бросить кость другим программистам, столкнувшимся с этой проблемой, превратив результаты своей работы и исследования в ответ.   -  person user4581301    schedule 31.05.2018
comment
Вместо этого я бы сосредоточился на поиске способа получить необходимую функциональность без использования t_data в первую очередь. (Это потребует большего контекста, чем в вопросе.)   -  person JaMiT    schedule 31.05.2018
comment
Да, определенно не вызывайте free или delete для указателя, возвращенного GetShortArrayElements, потому что вы не знаете, что GetShortArrayElements сделал внутри. Возможно, он вообще не выделил никакой памяти. Некоторые реализации просто закрепляют массив Java, чтобы избежать его перемещения сборщиком мусора, а затем возвращают указатель на фактическое содержимое массива Java. Просто вызовите ReleaseShortArrayElements, когда закончите с указателем.   -  person Michael    schedule 31.05.2018
comment
@Майкл или Ремалдип, вы должны опубликовать это как ответ.   -  person Tom Blodget    schedule 01.06.2018


Ответы (1)


То, что сказал Майкл, было правильным, и это действительно решило проблему. Ссылаясь на его комментарий:

Да, определенно не вызывайте free или delete для указателя, возвращаемого GetShortArrayElements, потому что вы не знаете, что GetShortArrayElements сделал внутри. Возможно, он вообще не выделил никакой памяти. Некоторые реализации просто закрепляют массив Java, чтобы избежать его перемещения сборщиком мусора, а затем возвращают указатель на фактическое содержимое массива Java. Просто вызовите ReleaseShortArrayElements, когда закончите с указателем. - Майкл

person Remaldeep    schedule 01.06.2018