Should I free the pointer returned by native method manually?

Red IO redio.development at gmail.com
Tue Jan 23 01:11:29 UTC 2024


Thanks Maurizio for the clear explanation.
Since last time I experimented with Panama the api changed a lot.
I will need to look more into what jextract generates to understand the
current api better.

Great regards
RedIODev

On Mon, Jan 22, 2024, 22:42 Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:

>
> 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/20240123/284f71d5/attachment.htm>


More information about the panama-dev mailing list