Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

swig question

31 views
Skip to first unread message

bill...@alum.mit.edu

unread,
Jan 13, 2007, 4:19:21 PM1/13/07
to
I am using swig to provide a Tcl interface to a C library. One function
returns a dynamically allocated string
which is assigned to "result" below. Swig returns this in Tcl as
follows:


Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1));


As I understand it, this creates a new copy of the string as part of
the newly created Tcl object. While Tcl's memory management handles the
copy, the string created by my C function will not be garbage collected
by Tcl, so as it stands, this is a memory leak.

Things seem to work just fine if I add to the code generated by swig:


free((void *) result);


after the call to TclSetObjResult.


My questions are:

(a) have I misunderstood anything here?

(b) is there a way to get swig to free the C string so that I don't
have to do it by editing the output of swig?

(c) if I distribute my edited version of the wrapper file generated by
swig, will it be portable? That is, is the code generated by swig
system-dependent? I can't find anything in the swig documentation about
this.

Georgios Petasis

unread,
Jan 13, 2007, 5:22:01 PM1/13/07
to bill...@alum.mit.edu
O/H bill...@alum.mit.edu έγραψε:
In general, I *do not* modify swig generated code. But to be sure, its
better to post your function part that the string is returned, its
prototype and the whole wrapper function generated by swig :-)

George

Robert Heller

unread,
Jan 13, 2007, 5:31:21 PM1/13/07
to
At 13 Jan 2007 13:19:21 -0800 bill...@alum.mit.edu wrote:

>
> I am using swig to provide a Tcl interface to a C library. One function
> returns a dynamically allocated string
> which is assigned to "result" below. Swig returns this in Tcl as
> follows:
>
>
> Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1));
>
>
> As I understand it, this creates a new copy of the string as part of
> the newly created Tcl object. While Tcl's memory management handles the
> copy, the string created by my C function will not be garbage collected
> by Tcl, so as it stands, this is a memory leak.
>
> Things seem to work just fine if I add to the code generated by swig:
>
>
> free((void *) result);
>
>
> after the call to TclSetObjResult.
>
>
> My questions are:
>
> (a) have I misunderstood anything here?

No.

>
> (b) is there a way to get swig to free the C string so that I don't
> have to do it by editing the output of swig?
>

Yes. You need to write a typemap for this case. This will allow you to
include some special handling.

> (c) if I distribute my edited version of the wrapper file generated by
> swig, will it be portable? That is, is the code generated by swig
> system-dependent? I can't find anything in the swig documentation about
> this.

The code generated by swig is cross-platform. Any code you insert
(manually or via a typemap) might or might not be. If you are using
autoconf and/or TEA you should make sure all the generated -D<mumble>
flags are passed to your swig call (in your Makefile.in) and then you
can test them with #ifdef's (in the typemap code) to be sure you
generate portable code. Presumbably, your C library is doing this, in
terms of it calling the proper flavor of malloc()/calloc(), etc. and
you can use these flags to call the matching flavor of free().

>
>

--
Robert Heller -- 978-544-6933
Deepwoods Software -- Linux Installation and Administration
http://www.deepsoft.com/ -- Web Hosting, with CGI and Database
hel...@deepsoft.com -- Contract Programming: C/C++, Tcl/Tk

bill...@alum.mit.edu

unread,
Jan 13, 2007, 6:36:44 PM1/13/07
to
I am using swig to provide a Tcl interface to a C library. One
function returns a dynamically allocated string which is assigned to
"result" below. Swig returns this in Tcl as follows:


Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1));


As I understand it, this creates a new copy of the string as part of
the newly created Tcl object. While Tcl's memory management handles the
copy, the string created by my C function will not be garbage collected

by Tcl, so as it stands, this is a memory leak: every call to the Tcl
function will cause my C function to allocate a new string that will
not be garbage collected by Tcl.


Things seem to work just fine if I add to the code generated
by swig:


free((void *) result);


after the call to TclSetObjResult.


My questions are:

(a) have I misunderstood anything here?

(b) is there a way to get swig to free the C string so that I don't
have to do it by editing the output of swig?

(c) if I distribute my edited version of the wrapper file generated by
swig, will it be portable? That is, is the code generated by swig

system-dependent? Or must I write a script to insert the free()into the
code generated by swig?

pal...@yahoo.com

unread,
Jan 14, 2007, 9:05:07 PM1/14/07
to
You need a "ret" typemap to free the return string.
For example, something along the following lines

%{
typedef char * malloced_str;
%}
%typemap(out) malloced_str %{
if ($1 == NULL) {
/* Assumes NULL return is a failure */
Tcl_SetResult(interp, ........);
SWIG_fail;
}
else {
Tcl_SetObjResult(interp, Tcl_NewStringObj($1, -1));
}
%}
%typemap(ret) malloced_str "if ($1) free($1);"

malloced_str my_function();


Note this assumes the function returns the string as a return value. If
it is passed out through a parameter poiunter, you will need a
typemap(argout) that does something similar

/Ashok

bill...@alum.mit.edu

unread,
Jan 15, 2007, 12:41:16 PM1/15/07
to
Thanks, but there seems to be a simpler way to deal with this
particular problem, which I eventually found in the Swig manual while
studying typemaps. In my .i file I include the declaration:

%newobject UNStrToWNStr;

That tells Swig that the function returns newly allocated memory and
induces it to add a free by itself in the _wrap.c file.

Incidentally, the reason I posted twice is that the first one didn't
appear for a very long time, over an hour, so I mistakenly concluded
that something had gone wrong. After it appeared, I was unable to
respond to posts in this thread. Every time I clicked on the "Reply"
button I got an error message. Anyone know what was wrong?

Bill

0 new messages