On Tue, 3 Dec 2013 19:59:22 -0800 (PST)
David Buchan <pdbuc...@yahoo.com> wrote:
> ok, I may be getting somewhere. I did some reading on heap memory
> versus stack.
> 
> Here's a vastly simplified example program which doesn't use GTK+,
> but I'm using to demonstrate my plan of attack.
> 
> I use a function called packit() which allows me to still use
> strdup().
> 
> Comments?
> 
> Dave
> 
> 
> Valgrind is happy with this:
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
> 
> typedef struct _msgdata msgdatas;
> struct _msgdata {
>   char *message;
>   int *textview;
> };
> 
> msgdatas *packit (msgdatas *, char *);
> int myfunc (msgdatas *);
> 
> int
> main (int argc, char ** argv)
> {
>   int i;
>   char *message;
>   msgdatas *msgdata;
> 
>   // Allocate memory on the heap, not stack.
>   msgdata = (msgdatas *) malloc (1 * sizeof (msgdatas));
>   msgdata->textview = (int *) malloc (1 * sizeof (int));
>   message = (char *) malloc (1024);
> 
>   // Main loop.
>   for (i=0; i<100; i++) {
>     sprintf (message, "%i Dave is here.", i);  // In reality, this is
> a more complicated sprintf().
> 
>     *(msgdata->textview) = 7;  // This is a stand-in for a pointer to
> a textview. myfunc (packit (msgdata, strdup (message)));  // strdup()
> allocates memory for message on the heap.
> 
>     sprintf (message, "%i Dave is no longer here.", i);  // In
> reality, this is a more complicated sprintf().
> 
>     *(msgdata->textview) = 3;  // This is a stand-in for a pointer to
> a textview; only changed for fun. myfunc (packit (msgdata, strdup
> (message)));  // strdup() allocates memory for message on the heap. }
> 
>   // Don't free msgdata->message; it gets free'd by myfunc().
>   free (msgdata->textview);
>   free (msgdata);
>   free (message);
> 
>   return (EXIT_SUCCESS);
> }
> 
> msgdatas *
> packit (msgdatas *msgdata, char *message)
> {
>   msgdata->message = message;
> 
>   return (msgdata);
> }
> 
> // This is a stand-in for an idle function which would update the
> textview in the UI. int  // Would really be gboolean
> myfunc (msgdatas *data)
> {
>   printf ("Pointer to textview: %i\n", *(data->textview));
>   printf ("message: %s\n", data->message);
> 
>   // Only free the element "message" of msgdatas struct.
>   free (data->message);
> 
>   return (EXIT_SUCCESS);  // Would really be return (G_SOURCE_REMOVE)
> }

I don't really understand what you are trying to do.  It seems bizarre
to allocate a pointer to a textview on the heap (it seems completely
unnecessary), and even more bizarre then to free it again in the same
thread.  In fact I have no idea why you are passing a pointer to a text
view at all: that sounds like shared data (you shouldn't create a
GtkTextView except in the main loop thread), which may defeat part of
the purpose of the exercise.  If the worker thread can see the textview
then presumably so can the main thread.  If myfunc() is a stand-in for
g_idle_add(), then there is also a clear error in freeing msgdata and
its textview member in main(), and using these in myfunc(). You should
free the struct and any of its members which need freeing in myfunc()
(the g_idle_add() stand-in). Furthermore your call to strdup() is
completely unnecessary as 'message' has already been allocated on the

heap.

I may be wrong but I get the impression you do not know much about C.
You need to take some basic tuition on the use of C pointers and on
memory allocation as a minimum.  Learning C is a good thing to do if
you are serious about programming but you cannot run until you can
walk.  I would caution you against trying to program with threads,
which bring in a host of new issues concerning synchronization, at your
level of understanding.  Having said that, if you want to plough on
regardless, then good on you, as you need to start somewhere and learn
from there.  Possibly you already know about how to use threads safely
from another language, in which case fine.

Otherwise, have you considered perhaps using something like the python
bindings for GTK+?  These have a binding for g_idle_add() and handle
all the memory allocation for you.  I recommend using the
gobject-introspection binding for GTK+-3 rather than the old pygtk for
GTK+-2.  Python is another language which is worth learning.  There are
also introspection bindings for javascript if you prefer that (although
you won't be able to use threads in javascript - but that may be an
advantage for you).

Chris

====================
The example above has main() calling the idle function, but in reality, it's a 
thread. That thread receives a pointer to the textview from main(). The idle 
function needs to access the textview, but it needs g_idle_add() to send a 
pointer to the textview to it, otherwise it won't be able to access it. But it 
also needs access to the message, thus I pack the two items in a struct.

For the purposes of demonstration, the int is standing-in for a textview. I 
don't really allocate it as you see in this example. I'm just trying to show I 
can pass the two items in a struct using packit().

I didn't think my C was that bad. :o(
Dave
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to