Should I free the pointer returned by native method manually?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Jan 22 21:42:20 UTC 2024


On 22/01/2024 20:01, Red IO wrote:
> I know that the original question is answered, but how would you free 
> memory in case the libraries documentation says to use free. Would you 
> just create a method handle to libc free and call it with the pointer 
> or is there an api to free native memory?

If the API says to use free, then you should have a downcall method 
handle for "free" and call that (using the same technique with 
MemorySegment::reinterpret I showed in the last email).

(Note: when using jextract, chances are that "free" will come along for 
the ride in the extracted classes).

Maurizio

> Great regards
> RedIODev
>
> On Mon, Jan 22, 2024, 19:36 Maurizio Cimadamore 
> <maurizio.cimadamore at oracle.com> wrote:
>
>     Hi tison,
>     in this case, the function is returning a pointer. What happens to
>     that
>     pointer is 100% library-dependent. In this case, doing `man getpwnam`
>     gives us some clues:
>
>     > The return value may point to a static area, and may be
>     overwritten  by
>     >        subsequent  calls  to  getpwent(3), getpwnam(), or
>     getpwuid().
>     > (Do not
>     >        pass the returned pointer to free(3).)
>
>     Basically, the returned pointer points to an area that is managed
>     by the
>     library, so you don't have to free.
>
>     This means the code you have seems correct to me.
>
>     Other libraries will behave differently, for instance they might
>     have a
>     pair of functions such as "createFoo" and "destroyFoo", the former
>     allocating region of memory, and the latter destroying such
>     region. In
>     such cases it might be helpful to associate the return memory
>     segment to
>     an existing arena *and* also attach a cleanup function (via
>     MemorySegment::reinterpret), so that, when the arena is closed,
>     "destroyFoo" is called on the pointer.
>
>     Hope this helps
>
>     Maurizio
>
>
>     On 22/01/2024 18:28, tison wrote:
>     > Here is the code snippet:
>     >
>     >      public static void main(String[] args) throws Throwable {
>     >          final Linker linker = Linker.nativeLinker();
>     >          final SymbolLookup libc = linker.defaultLookup();
>     >          final MethodHandle handle =
>     > linker.downcallHandle(libc.find("getpwnam").orElseThrow(),
>     > FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS));
>     >          try (Arena arena = Arena.ofConfined()) {
>     >              final MemorySegment passwd = (MemorySegment)
>     > handle.invoke(arena.allocateUtf8String("tison"));
>     >              System.out.println("passwd=" + passwd);
>     >              System.out.println("pw_name=" +
>     > passwd.reinterpret(Long.MAX_VALUE).get(ValueLayout.ADDRESS,
>     > 48).reinterpret(Long.MAX_VALUE).getUtf8String(0));
>     >          }
>     >      }
>     >
>     > I wonder if I should explicitly free passwd that is returned from a
>     > native method. If so, how? If not, how the Arena tracks it and
>     free on
>     > closed?
>     >
>     > Best,
>     > tison.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20240122/722db139/attachment-0001.htm>


More information about the panama-dev mailing list