Re: Another GNode question



{reposted in text format, sorry}

vladimir wrote:


#include <glib.h>

int
main (int argc, char *argv[])
{
        GNode *node;
        GArray *array1;
        GArray *array2;
        guint number;
        
        node = g_node_new (NULL);
        array1 = g_array_new (FALSE, FALSE, sizeof (guint));
        
        number = 2;
        array1 = g_array_append_val (array1, number);
        
        number = 5;
        array1 = g_array_append_val (array1, number);
        
        number = 4;
        array1 = g_array_append_val (array1, number);
        
        node->data = g_memdup (array1, sizeof (array1) * array1->len);
        

This line is completely broken:
0) GArray uses the *data* pointer to point the data. Assume you've alloced the data at address 0x00400000 and initialized the pointer to it. Then you're copying data with g_memdup to address 0x00400100, your pointer value stays at 0x00400000. All looks
right till you free the data at 0x00400000.
1) Variable array1 is a pointer, as I see you've expected that you would get a size of GArray structure, but you will get an arch-depended size of pointer (4 for the modern x86 running pm). 2) GArray is a public top of a larger structure GRealArray. You cant just copy *sizeof(GArray)+sizeof(YourData)*array->len* bytes of memory. You have to create a new array and fill it with values of an old one.


        g_array_free (array1, TRUE);
                
        array2 = (GArray *)node->data;
        g_print ("testing...\n");
        g_print ("array2, (1): %d\n", g_array_index (array2, guint, 0));
        g_print ("array2, (2): %d\n", g_array_index (array2, guint, 1));
        g_print ("array2, (3): %d\n", g_array_index (array2, guint, 2));
        
        return 0;
}

So if I free array1 like this: g_array_free (array1, TRUE); the result
is:
testing...
array2, (1): 1078834872
array2, (2): 1078834872
array2, (3): 667182
(junk memory)

That's ok - array1 is freed, so data can be overwritten.


But, if I __DON'T__ free array, the result is:
testing...
array2, (1): 2
array2, (2): 5
array2, (3): 4

That's ok too - cause you've copied the pointer and data lying at the same addresses.


Doesn't g_memdup copies mem? Or I'm missing something else? I'm using
GLib 2.0.6 & GTK+ 2.0.6.

Cut from GLib reference (you can reach it @ gtk.org):


     g_memdup ()

gpointer <mailbox:///home/ath/.mozilla/ath/sy6a9i4u.slt/Mail/cs-1.stu/Sent?number=2201165&part=1.2>    g_memdup         
               (gconstpointer 
<mailbox:///home/ath/.mozilla/ath/sy6a9i4u.slt/Mail/cs-1.stu/Sent?number=2201165&part=1.3> mem,
                                            guint 
<mailbox:///home/ath/.mozilla/ath/sy6a9i4u.slt/Mail/cs-1.stu/Sent?number=2201165&part=1.4> byte_size);

Allocates /byte_size/ bytes of memory, and copies /byte_size/ bytes into it from /mem/. If /mem/ is NULL it returns NULL .


Olexiy






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]