I want to choose a several files and write their path to TextView widget by click on the button. I have memory leaks and dont understand how to properly free memory. Sometimes my application is not starting at all, sometimes for second click I have segmentation fault. Also there are this errors every time:
GLib-CRITICAL **: 14:48:38.184: g_main_context_pop_thread_default: assertion 'g_queue_peek_head (stack) == context' failed
GLib-CRITICAL **: 14:48:42.576: g_hash_table_contains: assertion 'hash_table != NULL' failed
GLib-CRITICAL **: 14:48:42.586: g_hash_table_insert_internal: assertion 'hash_table != NULL' failed
Segmentation fault
Callback functions in C for file dialog is below:
static void
choseTargetFinish (GObject* source_object, GAsyncResult* res, gpointer data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source_object);
GListModel *files = gtk_file_dialog_open_multiple_finish(dialog, res, NULL);
if (files != NULL)
{
GtkTextIter *start;
GtkTextIter *end;
gtk_text_buffer_get_start_iter(targetPathBuffer, start);
gtk_text_buffer_get_end_iter(targetPathBuffer, end);
gtk_text_buffer_delete(targetPathBuffer, start, end);
GFile *file;
char *path;
int i = 0;
file = g_list_model_get_item(files, i);
end = start;
while (file != NULL)
{
path = g_file_get_path(file);
sprintf(path, "%sn", path);
gtk_text_buffer_insert(targetPathBuffer, end, path, -1);
gtk_text_buffer_get_end_iter(targetPathBuffer, end);
i++;
file = g_list_model_get_item(files, i);
}
g_free(path);
}
}
static void
chooseTarget_cb (GtkWidget *widget)
{
GtkFileDialog *fd = gtk_file_dialog_new();
GAsyncResult* result;
gtk_file_dialog_open_multiple(fd, NULL, NULL, choseTargetFinish, NULL);
g_object_unref(fd);
}
I read docs and it says I should free GListModel and I tried to do it by g_object_unref.
Yonett is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
There are a few issues with the provided code that could lead to the segmentation faults and memory leaks you’re encountering. I’ll break down the key points:
-
Iterators Initialization: You are passing uninitialized pointers (
start
andend
) togtk_text_buffer_get_start_iter
andgtk_text_buffer_get_end_iter
. These need to be validGtkTextIter
objects, not pointers to them. You should declare them as actual variables, not pointers. -
Memory Management: You are not properly managing the memory of
GListModel
,GFile
, and the strings returned byg_file_get_path
. The memory needs to be released once you are done with it. -
Avoid
sprintf
onpath
: You are usingsprintf
directly on thepath
pointer, which is already pointing to a string allocated byg_file_get_path
. This is unnecessary and could lead to unexpected behavior. Instead, use a temporary buffer to append the newline character.
This is an updated version of your callback function:
static void
choseTargetFinish (GObject* source_object, GAsyncResult* res, gpointer data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source_object);
GListModel *files = gtk_file_dialog_open_multiple_finish(dialog, res, NULL);
if (files != NULL)
{
// Declare actual GtkTextIter variables (not pointers)
GtkTextIter start, end;
// Clear the TextView content
gtk_text_buffer_get_start_iter(targetPathBuffer, &start);
gtk_text_buffer_get_end_iter(targetPathBuffer, &end);
gtk_text_buffer_delete(targetPathBuffer, &start, &end);
// Iterate over the selected files
for (int i = 0; i < g_list_model_get_n_items(files); i++)
{
GFile *file = G_FILE(g_list_model_get_item(files, i));
if (file != NULL)
{
// Get the file path
char *path = g_file_get_path(file);
if (path != NULL)
{
// Append newline and insert into TextView
char *formatted_path = g_strdup_printf("%sn", path);
gtk_text_buffer_get_end_iter(targetPathBuffer, &end);
gtk_text_buffer_insert(targetPathBuffer, &end, formatted_path, -1);
// Free the path and formatted_path
g_free(path);
g_free(formatted_path);
}
// Unref the GFile object
g_object_unref(file);
}
}
// Unref the GListModel after use
g_object_unref(files);
}
}
The main changes I made are:
- GtkTextIter Variables: I changed
GtkTextIter *start, *end
to actualGtkTextIter start, end
variables and passed their addresses togtk_text_buffer_get_start_iter
andgtk_text_buffer_get_end_iter
. - Memory Management:
- Added
g_free()
for thepath
andformatted_path
strings. - Unreferenced each
GFile
object withg_object_unref(file)
after processing it. - Unreferenced the
GListModel
after looping through the files withg_object_unref(files)
.
- Added
- Formatted Path: Used
g_strdup_printf
to safely create a new string with the newline (n
) and free it afterward.
This should resolve the segmentation faults, memory leaks, and the error messages you’re seeing.
1