Re: garray beginner problem




garray = g_array_new (FALSE, FALSE, sizeof (Machine));
for (i = 1; i < 10000; i++){
Machine *newMach = machine_new(i,"trd11","d11","joe");
g_array_append_val (garray, newMach);

Two problems here: You pass a *pointer* to Machine, not
a Machine, so a pointer is stored into garray. And newMach
is probably never freed.
You could copy the contents of newMach into the array,

I've never actually used GArray, but I'd expect that another alternative to either the options of using 
g_ptr_array, or copying the newly created machine into the array (with all the evils that idea comes with), 
would be to break the GObject pattern a little, by changing machine_new() into machine_init(), and taking the 
address of a machine struct as the first parameter.

This idea works particularly well if you know before hand, how many elements will be in the array.  Just 
create the array, set its size with g_array_set_size(), and then use your machine_init() on each element in 
turn.  (Like I said, I've never actually used a GArray...  But it should work)  Having said that, though, 
GArray (or even GPtrArray) are only likely to be of any use if the number of elements in the array is likely 
to change while the program is running.  If the number of machines will remain constant while the program's 
running, then as long as it's size is known before you have to actually allocate the array (for instance, 
your data file says there'll be 10 machines, and then presents the data for each machine), you can simply 
allocate memory for all 10, store it in a pointer to a machine struct, and then just go ahead and use it as a 
regular array.  It saves the ugly g_array_index buisness, at the expense of having to do a little extra work 
yourself.

Alternatively, you can use this approach quite well by creating a statically allocated machine struct with 
default values, appending that to your GArray (which involves copying the template into the new space), and 
then calling machine_init() to properly set it up.  This approach is particularly nice if you do happen to 
have a number of fields that need to be initialised to default values, as it saves having to do it in the 
machine_init() function...  This isn't entirely "safe", because you have to be careful to make sure that you 
always call machine_init() on a copy of the template struct.  But I've used this general technique myself on 
a number of occasions quite successfully.

A third way to approach the issue, based on the machine_init() method, is to actually allocate the machine 
struct on the heap (a simple variable of type struct machine), fill it in with machine_init(), and then 
append that to the GArray.  The original struct's memory will be released automatically when the function 
ends.  You can even re-use the one struct to build several machines, as long as your machine_init() totally 
initialises every member of the struct (which means it's not particularly compatible with the previous 
approach).

If you decide to go with the GPtrArray method instead, which has a few (fairly minor) advantages and 
disadvantages of its own, you can still have both options available by making your machine_new() function 
allocate memory for a new machine, and then call machine_init() on it, passing through all the arguments.  
That's basically what a GObject does anyhow.  The GObject type system allocates the memory, and gets all the 
ancestor types to initialise their parts of the memory, before yours gets to finish it off.


Fredderic

_______________________________________________
Join Excite! - http://www.excite.com
The most personalized portal on the Web!





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