2009-10-07 2 views
8

Так у меня есть этот C++ программе, которая вызывается с помощью JNI из моей Java программы, код следующим образом:JNI Освобождение памяти, чтобы избежать утечек памяти

JNIEXPORT jstring JNICALL Java_com_entrust_adminservices_urs_examples_authn_LdapAuthenticator2_takeInfo(JNIEnv *env, jobject obj, jstring domain, jstring id, jstring idca, jstring password) 
{ 
    const char *nt_domain; 
    const char *nt_id; 
    const char *nt_password; 
    HANDLE hToken = 0; 

    bool aut = false; 

    nt_domain = env->GetStringUTFChars(domain, NULL); 
    nt_id = env->GetStringUTFChars(id, NULL); 
    nt_password = env->GetStringUTFChars(password, NULL); 

     aut = LogonUser(nt_id, nt_domain, nt_password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken); 

     /* release buffers */ 
    env->ReleaseStringUTFChars(domain, nt_domain); 
    env->ReleaseStringUTFChars(id, nt_id); 
    env->ReleaseStringUTFChars(password, nt_password); 
    /* release the login handle */ 
    CloseHandle(hToken); 

    if(aut) 
    { 
     return env->NewStringUTF("true"); 
    } 

    DWORD dwError = GetLastError(); 
     LPVOID lpMsgBuf; 

     FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); 

    return env->NewStringUTF((const char*)lpMsgBuf); //returns the contents of lpMsgBuf (error) 
} 

в эту секунду до последней строки jstring newString = env->NewStringUTF((const char*)otherString); никогда не выпускалась, но вернулся , это приведет к возможной утечке памяти? есть все равно, чтобы обойти это?

Также возможно, что вместо того, чтобы возвращать строку, я возвращаю логическое значение (как было возвращено функцией LogonUser) вместо jstring и вместо этого добавляет в метод метод «errormessage» refpence и обновляет его ? моя программа Java сможет увидеть обновление до «errormessage»?

Спасибо.

ответ

8

NewStringUTF() создает новый java.lang.String - другими словами, объект на куче Java, который будет собираться, когда на нем больше нет ссылок.

Или вы спрашиваете о otherString? Я не знаю, что делает FormatMessage, но похоже, что он выделяет память на куче C. Если это так, то да, вы должны явно освободить эту память.

Вы делаете свою жизнь более трудной, иногда устанавливая otherString на постоянную строку. Не делай этого. Вместо этого позвоните по номеру NewStringUTF() в блоках вашего if/else, а во втором случае освободите собственную C-строку.

+0

спасибо за советы, я обновил код, если бы вы могли посмотреть и посмотреть, обнаружите ли вы какие-либо очевидные ошибки (im java guy workin в мире C++ прямо сейчас) –

+0

Вы все еще не освобождаете lpMsgBuf , Возможно, вам это не нужно; Я не знаю, выделяет ли метод FormatMessage() память или нет. – kdgregory

+0

спасибо kdgregory, так как я понимаю, что lpMsgBuf не нужно освобождать, но это нигде не существует, если все остальное правильно, спасибо снова –

6

Вам не нужно беспокоиться о памяти, выделенной NewStringUTF, о которой позаботится сборщик мусора Java.

Но вам нужно освободить lpMsgBuf, когда вы передаете FORMAT_MESSAGE_ALLOCATE_BUFFER в FormatMessage (то есть вы должны использовать LocalFree для освобождения этого буфера), см. Документацию FormatMessage.