C++ / JNI memory leakage, help needed

Discussion in 'C++' started by Sambucus, Apr 3, 2004.

  1. Sambucus

    Sambucus Guest

    Hi group!

    I am using C++ and java with JNI to get some text in a RICHEDIT to my
    java program. I do so by accessing a C++ method every second. It all
    works fine except that it leaks memory every call I make to the C++
    method.

    Can anyone please help me with this problem? I am not sure wether the
    leakage is in the C++ or java code. But i guess it's on the C++ side
    since I'm kind of newbee there.

    Is there perhaps a way to release the memory allocated for a LPTSTR in
    C++?
    Please take a look at the code below, it is the method i call every
    second from java. I belive it is the LPTSTR that is leaking, since it
    leaks more when the string gets larger.

    <---------------
    LPTSTR output;

    JNIEXPORT jstring JNICALL
    Java_JNIHandler_getDealerOutput(JNIEnv *env, jobject obj){

    size = SendMessage(
    (HWND) textarea, // handle to destination window
    WM_GETTEXTLENGTH, // message to send
    (WPARAM) 0,
    (LPARAM) 0 ) +1;

    output = new TCHAR[size];

    SendMessage(textarea,
    WM_GETTEXT,
    size,
    (LPARAM)(void*)output);

    return env->NewStringUTF(dealerStr);

    }
    ------------------>

    I have tried to release the memory allocated when the NewStringUTF is
    made with the JNI.h method env -> ReleaseStringUTFChars(str,
    dealerStr) to no avail.
    I hae also tried to use a try/finally block and in the finally set:
    output= NULL; delete output; but there is no difference.

    Cheers
    Andreas
    Sambucus, Apr 3, 2004
    #1
    1. Advertising

  2. Sambucus

    Chris Uppal Guest

    Sambucus wrote:

    > output = new TCHAR[size];


    This store is allocated but never freed. You need code to free it somewhere,
    like:

    delete [] output;
    output = 0; // or = NULL if you prefer


    > return env->NewStringUTF(dealerStr);


    Where does dealerStr come from ? Is this supposed to be 'output' ? I so then
    you should probably make 'output' be a local variable of
    Java_JNIHandler_getDealerOutput().

    I think you also may have problems with passing the text from the window to
    NewStringUTF(), that function requires bytes in a specific format that isn't
    "just plain text" (though it'll work with plain text in many cases). I don't
    think that'd be causing memory leaks, though, just "strange" Strings returned
    from your native method (or possibly crashing the JVM ;-)

    -- chris
    Chris Uppal, Apr 3, 2004
    #2
    1. Advertising

  3. "Sambucus" <> wrote in message
    news:...
    > Hi group!
    >
    > I am using C++ and java with JNI to get some text in a RICHEDIT to my
    > java program. I do so by accessing a C++ method every second. It all
    > works fine except that it leaks memory every call I make to the C++
    > method.
    >
    > Can anyone please help me with this problem? I am not sure wether the
    > leakage is in the C++ or java code. But i guess it's on the C++ side
    > since I'm kind of newbee there.
    >
    > Is there perhaps a way to release the memory allocated for a LPTSTR in
    > C++?
    > Please take a look at the code below, it is the method i call every
    > second from java. I belive it is the LPTSTR that is leaking, since it
    > leaks more when the string gets larger.
    >
    > <---------------
    > LPTSTR output;
    >
    > JNIEXPORT jstring JNICALL
    > Java_JNIHandler_getDealerOutput(JNIEnv *env, jobject obj){
    >
    > size = SendMessage(
    > (HWND) textarea, // handle to destination window
    > WM_GETTEXTLENGTH, // message to send
    > (WPARAM) 0,
    > (LPARAM) 0 ) +1;
    >
    > output = new TCHAR[size];
    >
    > SendMessage(textarea,
    > WM_GETTEXT,
    > size,
    > (LPARAM)(void*)output);
    >
    > return env->NewStringUTF(dealerStr);
    >
    > }
    > ------------------>
    >
    > I have tried to release the memory allocated when the NewStringUTF is
    > made with the JNI.h method env -> ReleaseStringUTFChars(str,
    > dealerStr) to no avail.
    > I hae also tried to use a try/finally block and in the finally set:
    > output= NULL; delete output; but there is no difference.


    finally is not part of the C++ language

    Try this

    jstring res = env->NewStringUTF(dealerStr);
    delete[] output;
    return res;

    I guess you are more of a Java programmer than a C++ programmer.

    Another method would be to use a vector, then you wouldn't have to worry
    about memory allocation.

    size = SendMessage(textarea, WM_GETTEXTLENGTH, 0, 0);
    std::vector<TCHAR> output(size + 1);
    SendMessage(textarea, WM_GETTEXT, size, (LPARAM)(void*)&output[0]);
    return env->NewStringUTF(&output[0]);

    I'm a bit hazy on the Windows and JNI details but the bottom line is that if
    you allocate memory with new[] then you have to free it with delete[], and
    if you use a vector then you don't have to deallocate at all.

    john
    John Harrison, Apr 3, 2004
    #3
  4. Sambucus

    Jeff Schwab Guest

    John Harrison wrote:
    > "Sambucus" <> wrote in message
    > news:...
    >
    >>Hi group!
    >>
    >>I am using C++ and java with JNI to get some text in a RICHEDIT to my
    >>java program. I do so by accessing a C++ method every second. It all
    >>works fine except that it leaks memory every call I make to the C++
    >>method.
    >>
    >>Can anyone please help me with this problem? I am not sure wether the
    >>leakage is in the C++ or java code. But i guess it's on the C++ side
    >>since I'm kind of newbee there.
    >>
    >>Is there perhaps a way to release the memory allocated for a LPTSTR in
    >>C++?
    >>Please take a look at the code below, it is the method i call every
    >>second from java. I belive it is the LPTSTR that is leaking, since it
    >>leaks more when the string gets larger.
    >>
    >><---------------
    >>LPTSTR output;
    >>
    >>JNIEXPORT jstring JNICALL
    >>Java_JNIHandler_getDealerOutput(JNIEnv *env, jobject obj){
    >>
    >>size = SendMessage(
    >>(HWND) textarea, // handle to destination window
    >>WM_GETTEXTLENGTH, // message to send
    >>(WPARAM) 0,
    >> (LPARAM) 0 ) +1;
    >>
    >>output = new TCHAR[size];
    >>
    >>SendMessage(textarea,
    >>WM_GETTEXT,
    >>size,
    >>(LPARAM)(void*)output);
    >>
    >>return env->NewStringUTF(dealerStr);
    >>
    >>}
    >>------------------>
    >>
    >>I have tried to release the memory allocated when the NewStringUTF is
    >>made with the JNI.h method env -> ReleaseStringUTFChars(str,
    >>dealerStr) to no avail.
    >>I hae also tried to use a try/finally block and in the finally set:
    >>output= NULL; delete output; but there is no difference.

    >
    >
    > finally is not part of the C++ language
    >
    > Try this
    >
    > jstring res = env->NewStringUTF(dealerStr);
    > delete[] output;
    > return res;
    >
    > I guess you are more of a Java programmer than a C++ programmer.
    >
    > Another method would be to use a vector, then you wouldn't have to worry
    > about memory allocation.
    >
    > size = SendMessage(textarea, WM_GETTEXTLENGTH, 0, 0);
    > std::vector<TCHAR> output(size + 1);
    > SendMessage(textarea, WM_GETTEXT, size, (LPARAM)(void*)&output[0]);
    > return env->NewStringUTF(&output[0]);
    >
    > I'm a bit hazy on the Windows and JNI details but the bottom line is that if
    > you allocate memory with new[] then you have to free it with delete[], and
    > if you use a vector then you don't have to deallocate at all.


    What John said, but consider using a std::basic_string<TCHAR> instead of
    std::vector<TCHAR>. The basic string in C++ has more Java-like syntax,
    e.g. the operator [ ] is range-checked, and concatenation can be done
    with operator +.
    Jeff Schwab, Apr 3, 2004
    #4
  5. >
    > What John said, but consider using a std::basic_string<TCHAR> instead of
    > std::vector<TCHAR>. The basic string in C++ has more Java-like syntax,
    > e.g. the operator [ ] is range-checked, and concatenation can be done
    > with operator +.


    But the problem with std::basic_string is that you cannot get a writable
    pointer from it. Therefore it's not suitable for passing to SendMessage(win,
    WM_GETTEXT ...).

    john
    John Harrison, Apr 3, 2004
    #5
  6. Sambucus

    Jeff Schwab Guest

    John Harrison wrote:
    >>What John said, but consider using a std::basic_string<TCHAR> instead of
    >>std::vector<TCHAR>. The basic string in C++ has more Java-like syntax,
    >>e.g. the operator [ ] is range-checked, and concatenation can be done
    >>with operator +.

    >
    >
    > But the problem with std::basic_string is that you cannot get a writable
    > pointer from it. Therefore it's not suitable for passing to SendMessage(win,
    > WM_GETTEXT ...).


    Thanks for clarifying, John. I don't know about SendMessage, and there
    was no prototype in the OP. I see now that the string was given no
    initializer, so it will need to be written.

    Why use a vector, though, instead of an automatic array?
    Jeff Schwab, Apr 3, 2004
    #6
  7. "Jeff Schwab" <> wrote in message
    news:...
    > John Harrison wrote:
    > >>What John said, but consider using a std::basic_string<TCHAR> instead of
    > >>std::vector<TCHAR>. The basic string in C++ has more Java-like syntax,
    > >>e.g. the operator [ ] is range-checked, and concatenation can be done
    > >>with operator +.

    > >
    > >
    > > But the problem with std::basic_string is that you cannot get a writable
    > > pointer from it. Therefore it's not suitable for passing to

    SendMessage(win,
    > > WM_GETTEXT ...).

    >
    > Thanks for clarifying, John. I don't know about SendMessage, and there
    > was no prototype in the OP. I see now that the string was given no
    > initializer, so it will need to be written.
    >
    > Why use a vector, though, instead of an automatic array?


    Because the size isn't known at compile time. Some compilers support arrays
    whose size is not known until runtime but its not standard C++.

    This is all Windows detail but

    SendMessage(textarea, WM_GETTEXTLENGTH, ...

    gets the length of text and

    SendMessage(textarea, WM_GETTEXT, ...

    gets the actual characters.

    john
    John Harrison, Apr 3, 2004
    #7
  8. Sambucus

    Yoyoma_2 Guest

    Chris Uppal wrote:

    > Sambucus wrote:
    >
    >
    >>output = new TCHAR[size];

    >
    >
    > This store is allocated but never freed. You need code to free it somewhere,
    > like:
    >
    > delete [] output;
    > output = 0; // or = NULL if you prefer


    This isn't java related but alwaise set your variables to NULL, since
    some platforms could exist that NULL is not defined as 0x0.
    Yoyoma_2, Apr 3, 2004
    #8
  9. On Sat, 03 Apr 2004 17:07:10 +0000, Yoyoma_2 wrote:

    > This isn't java related but alwaise set your variables to NULL, since
    > some platforms could exist that NULL is not defined as 0x0.


    I'm sure I've seen someone else on this group before say "Always set your
    variables to 0 rather than to NULL, some platforms may exist where NULL
    isn't defined as 0".

    James
    James Gregory, Apr 3, 2004
    #9
  10. Sambucus

    Jeff Schwab Guest

    James Gregory wrote:
    > On Sat, 03 Apr 2004 17:07:10 +0000, Yoyoma_2 wrote:
    >
    >
    >>This isn't java related but alwaise set your variables to NULL, since
    >>some platforms could exist that NULL is not defined as 0x0.

    >
    >
    > I'm sure I've seen someone else on this group before say "Always set your
    > variables to 0 rather than to NULL, some platforms may exist where NULL
    > isn't defined as 0".
    >
    > James
    >


    And they were right.

    Always use 0. The address represented by 0 is guaranteed in C++ to be
    the "null" value, whatever bit pattern that happens to be.
    Jeff Schwab, Apr 3, 2004
    #10
  11. Sambucus

    Yoyoma_2 Guest

    James Gregory wrote:
    > On Sat, 03 Apr 2004 17:07:10 +0000, Yoyoma_2 wrote:
    >
    >
    >>This isn't java related but alwaise set your variables to NULL, since
    >>some platforms could exist that NULL is not defined as 0x0.

    >
    >
    > I'm sure I've seen someone else on this group before say "Always set your
    > variables to 0 rather than to NULL, some platforms may exist where NULL
    > isn't defined as 0".


    Which group are you talking above (the list is pretty extensive).

    If you alwaise test on NULL then you are fine. What happends if you
    need to write to the 0x0 memory area in an albeit wierd platform. Using
    the NULL definition will eliviate that. Its also good practice. To me
    this is the same thing as doing sizeof( int ) instead of just putting
    "4". Cross-platform issues. This is what i've been tought but i am not
    professing it as necessarly right.

    >
    > James
    >
    Yoyoma_2, Apr 3, 2004
    #11
  12. Sambucus

    Jorge Rivera Guest

    John Harrison wrote:
    > "Sambucus" <> wrote in message
    > news:...
    >
    >>Hi group!
    >>
    >>I am using C++ and java with JNI to get some text in a RICHEDIT to my
    >>java program. I do so by accessing a C++ method every second. It all
    >>works fine except that it leaks memory every call I make to the C++
    >>method.
    >>
    >>Can anyone please help me with this problem? I am not sure wether the
    >>leakage is in the C++ or java code. But i guess it's on the C++ side
    >>since I'm kind of newbee there.
    >>
    >>Is there perhaps a way to release the memory allocated for a LPTSTR in
    >>C++?
    >>Please take a look at the code below, it is the method i call every
    >>second from java. I belive it is the LPTSTR that is leaking, since it
    >>leaks more when the string gets larger.
    >>
    >><---------------
    >>LPTSTR output;
    >>
    >>JNIEXPORT jstring JNICALL
    >>Java_JNIHandler_getDealerOutput(JNIEnv *env, jobject obj){
    >>
    >>size = SendMessage(
    >>(HWND) textarea, // handle to destination window
    >>WM_GETTEXTLENGTH, // message to send
    >>(WPARAM) 0,
    >> (LPARAM) 0 ) +1;
    >>
    >>output = new TCHAR[size];
    >>
    >>SendMessage(textarea,
    >>WM_GETTEXT,
    >>size,
    >>(LPARAM)(void*)output);
    >>
    >>return env->NewStringUTF(dealerStr);
    >>
    >>}
    >>------------------>
    >>
    >>I have tried to release the memory allocated when the NewStringUTF is
    >>made with the JNI.h method env -> ReleaseStringUTFChars(str,
    >>dealerStr) to no avail.
    >>I hae also tried to use a try/finally block and in the finally set:
    >>output= NULL; delete output; but there is no difference.

    >
    >
    > finally is not part of the C++ language
    >
    > Try this
    >
    > jstring res = env->NewStringUTF(dealerStr);
    > delete[] output;


    It's been a while since I last used JNI, but I think that strings that
    you create using NewStringUTF must be deleted (I don't remember the
    syntax for this).

    Check Sun's web site for more details on NewStringUTF...

    JLR
    Jorge Rivera, Apr 3, 2004
    #12
  13. Sambucus

    Chris Uppal Guest

    Yoyoma_2 wrote:
    > James Gregory wrote:
    > [...]
    > If you alwaise test on NULL then you are fine. What happends if you
    > need to write to the 0x0 memory area in an albeit wierd platform.


    You are wrong. The value 0 when used as a pointer has special defined
    semantics in both C and C++. Check the standards for the details.

    I'd write more except that:

    (a) this is cross-posted into areas where nobody is even slightly interested in
    the oddities of the C/C++ standards.

    (b) it's a few years since I last attempted public pedantry on these topics, so
    I'm a little rusty...

    -- chris
    Chris Uppal, Apr 3, 2004
    #13
  14. James Gregory wrote:

    > On Sat, 03 Apr 2004 17:07:10 +0000, Yoyoma_2 wrote:
    >
    >
    >>This isn't java related but alwaise set your variables to NULL, since
    >>some platforms could exist that NULL is not defined as 0x0.

    >
    >
    > I'm sure I've seen someone else on this group before say "Always set your
    > variables to 0 rather than to NULL, some platforms may exist where NULL
    > isn't defined as 0".
    >


    NULL must be a constant expression equal to 0. There is absolutely no
    difference between using NULL and 0.

    4.10 Pointer conversions [conv.ptr]

    1 A null pointer constant is an integral constant expression
    (_expr.const_) rvalue of integer type that evaluates to zero.



    18.1 Types [lib.support.types]

    [...]

    4 The macro NULL is an implementation-defined C++ null pointer constant
    in this International Standard (_conv.ptr_).180)

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Apr 3, 2004
    #14
  15. Sambucus

    Sambucus Guest

    >
    > finally is not part of the C++ language
    >
    > Try this
    >
    > jstring res = env->NewStringUTF(dealerStr);
    > delete[] output;
    > return res;
    >
    > I guess you are more of a Java programmer than a C++ programmer.
    >
    > Another method would be to use a vector, then you wouldn't have to worry
    > about memory allocation.
    >
    > size = SendMessage(textarea, WM_GETTEXTLENGTH, 0, 0);
    > std::vector<TCHAR> output(size + 1);
    > SendMessage(textarea, WM_GETTEXT, size, (LPARAM)(void*)&output[0]);
    > return env->NewStringUTF(&output[0]);
    >
    > I'm a bit hazy on the Windows and JNI details but the bottom line is that if
    > you allocate memory with new[] then you have to free it with delete[], and
    > if you use a vector then you don't have to deallocate at all.
    >
    > john


    You are certainly corect about me beeing a Java programer and not C++
    ;)
    I tried the first approach and it worked fine, thank you very much
    John!¨

    However i had tried to use something like this:

    return env->NewStringUTF(output);

    }
    __finally
    {
    output= NULL;
    delete [] output;
    size=NULL;

    ....and it did not work, i guess it has to do with the __finally not
    beeing part of c++? but why don't I get compilation a error?

    //Andreas
    Sambucus, Apr 4, 2004
    #15
  16. Sambucus

    Sambucus Guest

    > It's been a while since I last used JNI, but I think that strings that
    > you create using NewStringUTF must be deleted (I don't remember the
    > syntax for this).
    >
    > Check Sun's web site for more details on NewStringUTF...
    >
    > JLR


    Well i stumbled on info regarding this appearantly by Sun undocumented
    memory leakage in JNI when trying to solve my problem.

    However this is only when you are sending a java String to the C dll.
    In the C code you have to get a C string from the Java UTF chars...
    then you must use "env -> ReleaseStringUTFChars(str,output)" to
    release it
    Sambucus, Apr 4, 2004
    #16
  17. Sambucus

    lev Guest

    function c_str() returns const <CHAR_TYPE> *


    "John Harrison" <> wrote in message
    news:c4mbgi$2j5in4$-berlin.de...
    > >
    > > What John said, but consider using a std::basic_string<TCHAR> instead of
    > > std::vector<TCHAR>. The basic string in C++ has more Java-like syntax,
    > > e.g. the operator [ ] is range-checked, and concatenation can be done
    > > with operator +.

    >
    > But the problem with std::basic_string is that you cannot get a writable
    > pointer from it. Therefore it's not suitable for passing to

    SendMessage(win,
    > WM_GETTEXT ...).
    >
    > john
    >
    >
    lev, Apr 4, 2004
    #17
  18. "lev" <> wrote in message
    news:1gZbc.182893$Cb.1698658@attbi_s51...
    > function c_str() returns const <CHAR_TYPE> *
    >


    which is not a *writable* pointer

    john
    John Harrison, Apr 4, 2004
    #18
  19. On 3 Apr 2004 23:50:20 -0800, (Sambucus)
    wrote:

    >
    >However i had tried to use something like this:
    >
    >return env->NewStringUTF(output);
    >
    > }
    > __finally
    > {
    > output= NULL;
    > delete [] output;
    > size=NULL;
    >
    >...and it did not work, i guess it has to do with the __finally not
    >beeing part of c++? but why don't I get compilation a error?
    >


    C++ itself doesn't have a "finally" keyword, but Microsoft compilers
    support a "try-finally" construct as a language extension.

    The syntax is

    __try
    {
    }
    __finally
    {
    }

    The semantics are not quite the same as Java's "try-finally" - certain
    constructs can't be used within the guarded section, it can be broken
    by errant code and its use is not portable - but the idea is similar.

    George
    =============================================
    Send real email to GNEUNER2 at COMCAST o NET
    George Neuner, May 3, 2004
    #19
  20. Sambucus

    Asko Seeba Guest

    George Neuner wrote:
    > On 3 Apr 2004 23:50:20 -0800, (Sambucus)
    > wrote:
    >>However i had tried to use something like this:
    >>
    >>return env->NewStringUTF(output);
    >>
    >> }
    >> __finally
    >> {
    >> output= NULL;
    >> delete [] output;
    >> size=NULL;

    >
    > C++ itself doesn't have a "finally" keyword, but Microsoft compilers
    > support a "try-finally" construct as a language extension.

    [...]

    This is actually the first posting I am catching from this thread and
    sorry, if my posting is already hopelessly late, but what is the point
    of assigning NULL to output and then deleting the output (being NULL)?
    Shouldn't it be vice versa? For me, it seems like this is THE memory leak.

    --
    Asko Seeba
    Asko Seeba, May 5, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gaël

    w3wp crash and memory leakage

    Gaël, Oct 15, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    2,656
    Alvin Bruney
    Oct 16, 2003
  2. John Hilton

    How to identify the memory leakage...

    John Hilton, Dec 16, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    299
    John Hilton
    Dec 16, 2004
  3. Sambucus
    Replies:
    19
    Views:
    876
    George Neuner
    May 6, 2004
  4. Devian
    Replies:
    7
    Views:
    372
    Babu Kalakrishnan
    Sep 20, 2004
  5. E. Naubauer
    Replies:
    6
    Views:
    2,967
    Roedy Green
    Feb 24, 2006
Loading...

Share This Page