ReleaseStringUTFChars дает free (): неверный указатель: 0x0841a744 *** - PullRequest
0 голосов
/ 17 июля 2011


У меня есть библиотека на C ++, и я пишу функции-оболочки JNI, чтобы позволить мне вызывать ее из JAVA. У меня работает много разных функций, но у меня проблема с одной из них.
Функция, которую я пытаюсь обернуть, выглядит следующим образом:

void Set_Name(std::string invar)

У меня есть соответствующие вызовы GetStringUTFChars и ReleaseStringUTFChars следующим образом:

JNIEXPORT void JNICALL Java_com_metcarob_mys_javaapi_a_1SM_1D_1Orginisation_Set_1Name
  (JNIEnv *p_jEnv, jobject p_jObj, jlong p_nat, jstring invar) {
SM_D_Orginisation* p_SMD = (SM_D_Orginisation*) p_nat;
const char *pPp_invar2 = p_jEnv->GetStringUTFChars( invar, NULL );
if (NULL==pPp_invar2) return;
std::string *pPp_invar = new std::string(pPp_invar2);
p_SMD->Set_Name(*pPp_invar);
    pPp_invar2 = pPp_invar->c_str(); 
    p_jEnv->ReleaseStringUTFChars(invar, pPp_invar2);
    SAFE_DELETE(pPp_invar); 
  }

Я получаю исключение недопустимого указателя при запуске из Java:

*** glibc detected *** /home/robert/Oracle/Middleware/jdk160_21/bin/java: free(): invalid pointer: 0x0841a744 ***
======= Backtrace: =========
/lib32/libc.so.6(+0x6b511)[0xf7637511]
/lib32/libc.so.6(+0x6ce1b)[0xf7638e1b]
/lib32/libc.so.6(cfree+0x6d)[0xf763bf8d]
/home/robert/Oracle/Middleware/jdk160_21/jre/lib/i386/client/libjvm.so(+0x34fc8c)[0xf703bc8c]
/home/robert/Oracle/Middleware/jdk160_21/jre/lib/i386/client/libjvm.so(+0x25139a)[0xf6f3d39a]
/home/robert/Encrypted/Projects/Scout_Management/smbackend/DEBUG/libjavaapi.so(_ZN7JNIEnv_21ReleaseStringUTFCharsEP8_jstringPKc+0x27)[0xe02475c9]
/home/robert/Encrypted/Projects/Scout_Management/smbackend/DEBUG/libjavaapi.so(Java_com_metcarob_mys_javaapi_a_1SM_1D_1Orginisation_Set_1Name+0xd8)[0xe0245467]
[0xf4c0105d]

Если я удаляю вызов ReleaseStringURFChars, он работает без проблем. В документации говорится, что я должен вызывать ReleaseStringUTFChars для каждого вызова, который я выполняю в GetStringUTFChars, чтобы предотвратить утечки памяти.

Понятия не имею, что я делаю неправильно или что я должен проверять.
Кто-нибудь может помочь?
Спасибо
Роберт

1 Ответ

2 голосов
/ 17 июля 2011

Сначала вы получаете указатель с

const char *pPp_invar2 = p_jEnv->GetStringUTFChars( invar, NULL );

Но затем вы переназначаете указатель с помощью

pPp_invar2 = pPp_invar->c_str();

Сначала необходимо освободить память, а затем переназначить указатель.

Кроме того, вам не нужно выделять pPp_invar с помощью new, а затем удалять его, простого p_SMD->Set_Name(pPp_invar2); должно быть достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...