Re: Another GNode question



THANKS, once again Olexiy. As I see I haven't finished with pointers
yet. Still a lot to learn, but I __WILL__ try to be more careful. It is
pure __LOGIC__ now that You have explained it to me:) THANKS.

On Mon, 2002-10-21 at 10:04, Olexiy Avramchenko wrote:
{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]