I've started writing some plugins for geany on github, but I'm running into a problem. C is not my language of expertise, so I thought I would see if I'm just doing something stupid.
*The Problem:*
The basic problem is that I have a struct I'm using to pass information around like an object, but the information isn't staying with the struct when retrieving it from a TreeView.
*Steps to produce the issue:*
1. Open the plugin's configure window (Tools -> External Tools...) 2. Click the "New" button a few times. 3. Alternate which row of the TreeView is highlighted. 4. Note the checkboxes inconsistently are checked/unchecked on each item.
*The Code:*
https://github.com/sblatnick/geany-plugins/tree/external-tools/external-tool...
*Further Details:*
I create a GtkTreeView which I populate the only column with a struct called "Tool". Then, when the user clicks on a row in the table, it updates other UI components based on the Tool. I've already successfully overwritten the GtkTreeCellDataFunc to pull the name of the tool out, but for some reason the boolean checkboxes are updating rather randomly.
I'm guessing I'm not initializing the struct correctly, or that the pointer isn't handled correctly when storing/retreiving from the tree/table.
Also, one of the things I love about Geany is how little memory it uses, so feel free to give me pointers on when I need to free up memory, because I don't want my code to leak.
Currently I do a lot of Java, so any advice about pointers, memory allocation, and garbage clean-up are appreciated. Also, ideas for structuring C code into different files are appreciated.
Thanks,
Steve
On 02/04/2013 22:53, Steven Blatnick wrote:
I've started writing some plugins for geany on github, but I'm running into a problem. C is not my language of expertise, so I thought I would see if I'm just doing something stupid.
*The Problem:*
The basic problem is that I have a struct I'm using to pass information around like an object, but the information isn't staying with the struct when retrieving it from a TreeView.
I think the problem is this line: list = gtk_tree_store_new(1, G_TYPE_STRING);
later:
Tool *tool ... gtk_tree_store_set(list, &row, 0, tool, -1);
You should probably be using G_TYPE_POINTER instead of G_TYPE_STRING.
See: http://en.wikibooks.org/wiki/GTK%2B_By_Example/Tree_View/Tree_Models
"G_TYPE_STRING - stores a string in the store (makes a copy of the original string) G_TYPE_POINTER - stores a pointer value (does not copy any data into the store, just stores the pointer value!)"
Also, one of the things I love about Geany is how little memory it uses, so feel free to give me pointers on when I need to free up memory, because I don't want my code to leak.
Well, I didn't study your code for long, but: Tool *tool = g_slice_new(Tool);
Somehow you need to g_slice_free(Tool, tool) for each call to g_slice_new. Maybe by iterating the tree store when you've finished using it.
Le 03/04/2013 15:08, Nick Treleaven a écrit :
On 02/04/2013 22:53, Steven Blatnick wrote:
I've started writing some plugins for geany on github, but I'm running into a problem. C is not my language of expertise, so I thought I would see if I'm just doing something stupid.
*The Problem:*
The basic problem is that I have a struct I'm using to pass information around like an object, but the information isn't staying with the struct when retrieving it from a TreeView.
I think the problem is this line: list = gtk_tree_store_new(1, G_TYPE_STRING);
later:
Tool *tool ... gtk_tree_store_set(list, &row, 0, tool, -1);
You should probably be using G_TYPE_POINTER instead of G_TYPE_STRING.
[...]
Yep that's likely to be the issue.
Also, one of the things I love about Geany is how little memory it uses, so feel free to give me pointers on when I need to free up memory, because I don't want my code to leak.
Well, I didn't study your code for long, but: Tool *tool = g_slice_new(Tool);
Somehow you need to g_slice_free(Tool, tool) for each call to g_slice_new. Maybe by iterating the tree store when you've finished using it.
Yes. Actually in delete_tool() you call g_free() on the tool, but although the idea is correct (freeing the memory) you *MUST* use g_slice_free() to free memory allocated with g_slice_{alloc,new}(). GSlice is a separate allocator, so you can't use g_free() on memory you allocated with it.
You should probably add a new function next to new_tool() (e.g. free_tool()) that deals with freeing the memory for that tool, just the opposite of new_tool().
Also, you should always allocate the memory for the tool->name, and always free it before setting it. Here you have a leak in on_change(): g_strdup() allocate a copy of the string, but you don't free the old one. And you can only free the old one if it was allocated, so you need to make sure you always allocate it (e.g. in new_tool() you set tool->name = g_strdup(_("New tool"))), and in free_tool() you g_free(tool->name). And of course in on_change(), you g_free() tool->name before setting it to the new value.
Regards, Colomban