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