[Mono-list] Mono.Unix.Native.Syscall.readlink memory corruption

Andreas Färber andreas.faerber at web.de
Tue Mar 14 07:48:41 EST 2006


Kornél Pál schrieb:
>>>> On a related note:  if a C function mallocs some memory and returns a
>>>> pointer
>>>> to that memory, does p/invoke free the memory once marshalling is
>>>> complete?
>>>
>>> No. There is simply no way to automatically determine whether it
>>> should be
>>> freed and there is even less chance to determine how (using what
>>> function)
>>> it should be freed.
>>>
>>> If you want to do so you have to use an IntPtr that you can free
>>> manually.
>>> Note that you can alternatively use a custom marshaler but you have
>>> to do
>>> the same with a more complex and probably more proper design.
>> This is not entirely true. A returned string is actually automatically
>> freed when marshalled as string (as opposed to IntPtr). In that case
>> Mono does not determine whether it should be freed, it simply frees it.
>
> I don't think so. If you pass a buffer (that can be StringBuilder as
> well)
> the runtime will free any temporary allocated buffer and the GC will free
> the managed buffer. But that buffer is allocated by the caller so it
> can be
> freed easily. The buffer in question however is allocated by the
> callee and
> returned to caller. In this case the runtime will not free the buffer.
> You
> have to free it manually using the function mentioned in the
> documentation
> of the function that return the buffer becuase calling free() may not
> work
> as the buffer may come from other source. Also note that the returned
> buffer
> may come from some shared source so you should not free or modify it at.
> This latter case is unsafe but can provide better performance.
>
> I hope now you uderstand what kind of buffer are we talking about and
> why is
> it impossible for the runtime to free it automatically.
>
> Kornél
>
I was answering the very general question quoted at the top of my post.
That is not about a StringBuffer but about malloc and free in general,
so that your answer was correct in the specific case of passing a
StringBuffer as an argument (I did read that) but not in general to the
question of whether Mono frees unmanaged pointers:

char* unmanagedfunc() {
    return malloc(5);
}

will alloc 5 bytes,

extern static string unmanagedfunc();
string s = unmanagedfunc();

will marshal the string and free the unmanaged pointer.

I confirmed that Mono cannot determine whether a pointer is in use by
unmanaged code and complemented your answer with an exception where a
pointer is in fact freed by the runtime, which has caused some severe
problems for me in the past; don't know whether it is a bug or a feature
but it was observed in Mono 1.1.13 on OS X. If you don't think so then
test it yourself.

Andreas


More information about the Mono-list mailing list