On Thu, Dec 5, 2013 at 2:00 AM, David Buchan <pdbuc...@yahoo.com> wrote: > > Things I've learned yesterday are: > > 1. strdup() (I've never seen or used it before) > 2. what the heck heap and stack mean (still more to learn there) > 3. a more general and flexible solution is probably to use asynchronous > message queuing
"Heap" and "stack" are technically terms for particular data structures, but "the heap" and "the stack" generally refer to two particular memory stores: one that's global and from which memory can be (de)allocated arbitrarily, and one that's a strict queue and deallocates everything as things unwind. The stack is used for local variables (including function parameters) and function return values. The heap is used only by functions like malloc/free and their equivalents (including the C++ new/delete operators, though not alloca if you have it). There are other places stuff can be stuffed, like the static data segment for globals, and CPU registers, and such, but in terms of allocating strings like this, your options are limited there. I'll come back to the data segment later though. Everything allocated on the stack disappears when the current function returns. You can pass pointers around, but they'll be dangling (and very dangerous) once the function returns, so this is not thread-safe. Something allocated on the heap, on the other hand, stays around until it's explicitly freed. That means you have to put extra work into managing allocations and deallocations, but you can pass data around between threads this way. The rule is: Every successful allocation must be matched by exactly one deallocation. Anything else will give you either memory leaks or a corrupted heap, both of which are comparable to aiming a shotgun at your foot and pulling the trigger. As a general rule, you'll want to put temporary/working storage on the stack, and use the heap only when you need something to outlive the current function. That way, you minimize allocations/deallocations, which have run-time cost and (more importantly) need to be kept track of. Use the easy way unless you need the harder way. If you could manage the idle message with just a pointer to the string, that would be a lot easier. Does the message need to specify which of multiple textviews should be used, or is the info always going to go into the same one? If the latter, you can simply record that pointer in a global variable, which is stored in the data segment. That pointer is a fixed size, and it wants to outlive the function that puts it there (probably your initialization function), so the data segment (globals) is a good place for it. Something like this: static GtkWidget *textview; /****** thread *****/ void thread(int socket) { while (1) { char message[256]; size_t len=recv(socket,message,sizeof message-1,0); message[len]=0; g_idle_add((GSourceFunc)message_idle, strdup(message)); } } /****** idle handler, cribbed from your post earlier *****/ gboolean message_idle(char *message) { GtkTextBuffer *textbuffer; GtkTextIter end; textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)); gtk_text_buffer_get_end_iter (textbuffer, &end); gtk_text_buffer_insert (textbuffer, &end, message, -1); free(message); } /***** initialization *****/ int main() { /* ... */ textview = gtk_text_view_new(); /* start the thread etc */ } The textview doesn't actually matter to the worker thread - messages do. It shouldn't need to pass the textview to the idle handler. I've done this example as a very VERY simple socket handler; in a separate post I'll knock together a working example in Pike, to show how much easier this is in a high level language with asynchronous handlers. You can do similar things in Python, too, though for good async support in Python you might want to wait for version 3.4, which is now on its way (beta 1 released last week, estimated final release in February). ChrisA _______________________________________________ Hi Chris, Thanks for writing this. Definitely a keeper. Making the pointer to textview global would indeed simplify things enormously. I guess I avoid global variables like the plague, having been told to for years. Also wanted to make the idle function generic. Thanks again, Dave PS. Socket programming is great fun! ( http://pdbuchan.com/rawsock/rawsock.html ) _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list