comp.lang.ada
 help / color / mirror / Atom feed
* Free-ing memory: not springing leaks?
@ 2003-09-13 21:33 chris
  2003-09-14  1:10 ` Matthew Heaney
  0 siblings, 1 reply; 12+ messages in thread
From: chris @ 2003-09-13 21:33 UTC (permalink / raw)


Hi,

When you bind to c code, how do you deal with memory?  I bound to a 
function in Lua,

    function Lua_Version return ICS.Chars_Ptr;
    pragma Import (C, Lua_Version);

but upon free-ing the memory it gave a storage_error.

    function Version return String is
       X : ICS.Chars_Ptr := Lua_Version;
    begin
       declare
          Y : String := ICS.Value (X);
       begin
          ICS.Free (X);
          return Y;
       end;
    end Version;

To be clear, my understanding of this code is it get's a ptr to a null 
terminated string from Lua_Version, get's that value as a string, frees 
the null terminated string and returns the ada string.  Clearly, 
something is wrong with my understanding of how this works; if you free 
the memory it gives a storage error.

How then, do you deal with memory leaks?  If you bind to a c function 
and it allocates a chunk of memory and returns it, how do get rid of it 
and not cause leaks?  Remove Free and no error occurs.  Perhaps this is 
a special case?

I vaguely recall reading somewhere that in general you shouldn't free C 
allocated memory from Ada, but perhaps I was mistaken?


Can anyone please help with some advice or clarification?  I have only 
ever preallocated memory, passed it to a C function and released it 
afterwards (e.g. to pass strings into C functions) not had memory given 
by a c function and tried to release it.


Thanks,
Chris




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-13 21:33 Free-ing memory: not springing leaks? chris
@ 2003-09-14  1:10 ` Matthew Heaney
  2003-09-14 11:02   ` chris
  0 siblings, 1 reply; 12+ messages in thread
From: Matthew Heaney @ 2003-09-14  1:10 UTC (permalink / raw)


chris <spamoff.danx@ntlworld.com> writes:

> When you bind to c code, how do you deal with memory?  I bound to a
> function in Lua,
> 
>     function Lua_Version return ICS.Chars_Ptr;
>     pragma Import (C, Lua_Version);
> 
> but upon free-ing the memory it gave a storage_error.

You only free memory on the Ada side that has been allocated on the Ada
side.  If you have a ptr to memory that has been allocated on the C
side, there should also be a function to free that memory.

 
> How then, do you deal with memory leaks?  If you bind to a c function
> and it allocates a chunk of memory and returns it, how do get rid of it
> and not cause leaks?  Remove Free and no error occurs.  Perhaps this is
> a special case?

See above.

> I vaguely recall reading somewhere that in general you shouldn't free C
> allocated memory from Ada, but perhaps I was mistaken?

No, you are correct: don't do that.
 



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-14  1:10 ` Matthew Heaney
@ 2003-09-14 11:02   ` chris
  2003-09-14 12:51     ` Matthew Heaney
  0 siblings, 1 reply; 12+ messages in thread
From: chris @ 2003-09-14 11:02 UTC (permalink / raw)


Matthew Heaney wrote:

>>I vaguely recall reading somewhere that in general you shouldn't free C
>>allocated memory from Ada, but perhaps I was mistaken?
> 
> 
> No, you are correct: don't do that.

Thanks for the advice.

What if there is no call to free memory?  For example, the library 
loader for linux error mechanism is to return an error msg describing 
the problem.  Once you have it appears to be your problem what you do 
with it.  There is no call present in the library to return the memory.

Should I bind to a C compiled function to do this?  Perhaps in the case 
of linux, to the free function in the std lib?  I guess you are left to 
free it yourself in C because it provides "free" and it is natural to 
use it in C.


Chris





^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-14 12:51     ` Matthew Heaney
@ 2003-09-14 12:14       ` chris
  2003-09-14 14:24         ` Ludovic Brenta
                           ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: chris @ 2003-09-14 12:14 UTC (permalink / raw)


Matthew Heaney wrote:

 > chris.danx wrote:
>>For example, the library loader for linux error mechanism is to return
>>an error msg describing the problem.  Once you have it appears to be
>>your problem what you do with it.  There is no call present in the
>>library to return the memory.
> 
> This is an Ada binding?  Who wrote it?

No it is a C library for loading libraries at runtime.  Its' error 
handling returns errors as strings (customised to the library & call 
made) - though it'd be easier if it was ints, the errors can be for a 
variety of reasons but you need to parse them to handle them effectively!

const char *dlerror(void);

I wrote a binding to it, but did not know at the time free-ing C memory 
from Ada (with Interfaces.C.Strings.Free) was a no-no.  The binding 
takes the error message, converts it to an Ada string, free's the memory 
of the C string (with Interfaces.C.Strings.Free) and raises an exception 
tagged with the Ada String.

I will change this soon to use the native C compilers/libs "Free" (I 
forgot this when making the initial post.  I have free'd c memory from 
ada before).


> If you know it was malloc'd, then yes, just write a binding to free and
> call that.

And if you don't, then it's hit and miss? ... it figures.   I wonder how 
C programmers deal with this :(


Thanks for your help, it's much appreciated.


Chris




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-14 11:02   ` chris
@ 2003-09-14 12:51     ` Matthew Heaney
  2003-09-14 12:14       ` chris
  0 siblings, 1 reply; 12+ messages in thread
From: Matthew Heaney @ 2003-09-14 12:51 UTC (permalink / raw)


chris <spamoff.danx@ntlworld.com> writes:

> What if there is no call to free memory?

Then your binding is missing at least one operation.


> For example, the library loader for linux error mechanism is to return
> an error msg describing the problem.  Once you have it appears to be
> your problem what you do with it.  There is no call present in the
> library to return the memory.

This is an Ada binding?  Who wrote it?

 
> Should I bind to a C compiled function to do this?  Perhaps in the
> case of linux, to the free function in the std lib?  I guess you are
> left to free it yourself in C because it provides "free" and it is
> natural to use it in C.

If you know it was malloc'd, then yes, just write a binding to free and
call that.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-14 12:14       ` chris
@ 2003-09-14 14:24         ` Ludovic Brenta
  2003-09-14 19:00           ` chris
  2003-09-14 16:06         ` Simon Wright
  2003-09-18 20:15         ` Warren W. Gay VE3WWG
  2 siblings, 1 reply; 12+ messages in thread
From: Ludovic Brenta @ 2003-09-14 14:24 UTC (permalink / raw)


chris <spamoff.danx@ntlworld.com> writes:

> Matthew Heaney wrote:
> > If you know it was malloc'd, then yes, just write a binding to free and
> > call that.
> 
> And if you don't, then it's hit and miss? ... it figures.   I wonder
> how C programmers deal with this :(

This is supposedly documented by your library.  Some libraries return
"statically allocated" memory which you must not free.  This is for
example the case of readdir(3).

In the particular case of dlerror(3), I've just had a look at the
sources because the documentation is very evasive about this.  As it
turns out, dlerror() runs in one of two modes, thread-safe or not.

In thread-safe mode, it allocates a dynamic block of memory for each
thread.  This block contains a pointer to the string returned.  The
function allocates and frees this pointer, and _you should not free
the memory yourself_, because you cannot set the pointer to NULL
(remember that C is pass-by-value only, so what you receive from
dlerror() is a copy of the pointer).

If for some reason, dlerror() cannot use thread-safe mode, it falls
back to a thread-unsafe mode in which there is a single, statically
allocated, block of memory containing the pointer to the error string.
As before, dlerror() allocates and frees the memory for the string.

If you wand to forcefully free the memory, your best bet is to call
dlerror() twice, like this (I have not tried to compile this, mind
you):

Dynamic_Loader_Error : Exception;
procedure Dl_Error is
   function dlerror returns Interfaces.C.Strings.chars_ptr;
   pragma Import (C, dlerror, "dlerror");
   Error_Message : Interfaces.C.Strings.chars_ptr := dlerror;
   use type Interfaces.C.Strings.chars_ptr;
begin
   if Error_Message /= Interfaces.C.Strings.Null_Ptr then
      declare
         S : String := Interfaces.C.Strings.Value (Error_Message);
      begin
         Error_Message := dlerror; -- ask it to free the memory
         Ada.Exceptions.Raise_Exception (Dynamic_Loader_Error'Identity, S);
      end if;
   end if;
end Dl_Error;

-- 
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-14 12:14       ` chris
  2003-09-14 14:24         ` Ludovic Brenta
@ 2003-09-14 16:06         ` Simon Wright
  2003-09-15  7:13           ` Martin Krischik
  2003-09-18 20:15         ` Warren W. Gay VE3WWG
  2 siblings, 1 reply; 12+ messages in thread
From: Simon Wright @ 2003-09-14 16:06 UTC (permalink / raw)


chris <spamoff.danx@ntlworld.com> writes:

> I wrote a binding to it, but did not know at the time free-ing C
> memory from Ada (with Interfaces.C.Strings.Free) was a no-no.

I am pretty sure that in GNAT Interfaces.C.Strings.Free is an alias to
the C free; but there seems to be nothing in the ARM to guarantee
that.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-14 14:24         ` Ludovic Brenta
@ 2003-09-14 19:00           ` chris
  0 siblings, 0 replies; 12+ messages in thread
From: chris @ 2003-09-14 19:00 UTC (permalink / raw)



Thanks Ludovic, this is a great help.  I have fixed DLibs and released 
DLibs 0.11 with the corrections.  It now no longer free's the memory 
returned by dlerror and relies on the library to manage it as you described.

> This is supposedly documented by your library.  Some libraries return
> "statically allocated" memory which you must not free.  This is for
> example the case of readdir(3).

Yeah, as you point out it isn't always documented though.  What a pain! 




Thanks again,
Chris




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-14 16:06         ` Simon Wright
@ 2003-09-15  7:13           ` Martin Krischik
  0 siblings, 0 replies; 12+ messages in thread
From: Martin Krischik @ 2003-09-15  7:13 UTC (permalink / raw)


Simon Wright wrote:

> chris <spamoff.danx@ntlworld.com> writes:
> 
>> I wrote a binding to it, but did not know at the time free-ing C
>> memory from Ada (with Interfaces.C.Strings.Free) was a no-no.
 
> I am pretty sure that in GNAT Interfaces.C.Strings.Free is an alias to
> the C free; but there seems to be nothing in the ARM to guarantee
> that.

If you look cloesly at the GNAT Sources you will discover that GANT
internaly uses malloc and free.

But I am with Matthew here: On other compilers it might be different - so
don't us that knowlege.

With Regards

Martin.

-- 
mailto://krischik@users.sourceforge.net
http://www.ada.krischik.com




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-14 12:14       ` chris
  2003-09-14 14:24         ` Ludovic Brenta
  2003-09-14 16:06         ` Simon Wright
@ 2003-09-18 20:15         ` Warren W. Gay VE3WWG
  2003-09-19  3:02           ` Hyman Rosen
  2 siblings, 1 reply; 12+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-09-18 20:15 UTC (permalink / raw)


chris wrote:
> Matthew Heaney wrote:
> 
>  > chris.danx wrote:
> 
>>> For example, the library loader for linux error mechanism is to return
>>> an error msg describing the problem.  Once you have it appears to be
>>> your problem what you do with it.  There is no call present in the
>>> library to return the memory.
>>
>> This is an Ada binding?  Who wrote it?
> 
> No it is a C library for loading libraries at runtime.  Its' error 
> handling returns errors as strings (customised to the library & call 
> made) - though it'd be easier if it was ints, the errors can be for a 
> variety of reasons but you need to parse them to handle them effectively!
> 
> const char *dlerror(void);

There is no mention in the man pages that it is "allocated",
or that you should free it. Just like strerror(), you are
given a pointer to a human readable message, which you can
use, but not modify.

Unless you are given clear instructions to the contrary, do
_not_ free it.

If you want to decide the issue with 100% certainty, get the
Linux sources and examine how they use it.  But I would say
from my own extensive UNIX/Linux C experience, that you do
not need to worry about freeing this pointer.

> I wrote a binding to it, but did not know at the time free-ing C memory 
> from Ada (with Interfaces.C.Strings.Free) was a no-no. 

Well, as someone else pointed out, GNAT does use malloc() and
free() under the hood. In the interest of greater portability
however, I would code such that C allocated storage was
released in C code, and vice versa.

 > The binding
> takes the error message, converts it to an Ada string, 

Good..

> free's the memory 
> of the C string (with Interfaces.C.Strings.Free) 

..bad, in any language. ;-) It is not meant to be user freed
(just like strerror()).

> I will change this soon to use the native C compilers/libs "Free" 

Don't free it. It is not meant to be freed.

> And if you don't, then it's hit and miss? ... it figures.   I wonder how 
> C programmers deal with this :(

A lot of it is just a language lawyer's scrutiny of the man
pages!  However, with Linux/FreeBSD etc., the final truth
is contained in the source (Use the "source" Luke!)

> Thanks for your help, it's much appreciated.
> 
> Chris

Ada bindings can be so much fun.

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-18 20:15         ` Warren W. Gay VE3WWG
@ 2003-09-19  3:02           ` Hyman Rosen
  2003-09-19 13:07             ` Warren W. Gay VE3WWG
  0 siblings, 1 reply; 12+ messages in thread
From: Hyman Rosen @ 2003-09-19  3:02 UTC (permalink / raw)


Warren W. Gay VE3WWG wrote:
> There is no mention in the man pages that it is "allocated",
> or that you should free it.

In fact, on my Sun box, the dlerror man page explicitly says that
the returned value may point to a static area.




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Free-ing memory: not springing leaks?
  2003-09-19  3:02           ` Hyman Rosen
@ 2003-09-19 13:07             ` Warren W. Gay VE3WWG
  0 siblings, 0 replies; 12+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-09-19 13:07 UTC (permalink / raw)


Hyman Rosen wrote:
> Warren W. Gay VE3WWG wrote:
> 
>> There is no mention in the man pages that it is "allocated",
>> or that you should free it.
> 
> In fact, on my Sun box, the dlerror man page explicitly says that
> the returned value may point to a static area.

There is hope for documentation yet! ;-)

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2003-09-19 13:07 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-13 21:33 Free-ing memory: not springing leaks? chris
2003-09-14  1:10 ` Matthew Heaney
2003-09-14 11:02   ` chris
2003-09-14 12:51     ` Matthew Heaney
2003-09-14 12:14       ` chris
2003-09-14 14:24         ` Ludovic Brenta
2003-09-14 19:00           ` chris
2003-09-14 16:06         ` Simon Wright
2003-09-15  7:13           ` Martin Krischik
2003-09-18 20:15         ` Warren W. Gay VE3WWG
2003-09-19  3:02           ` Hyman Rosen
2003-09-19 13:07             ` Warren W. Gay VE3WWG

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox