Speicherleck mit sanitize, aber nicht mit velgrind?

Ich habe mehrere C-Dateien erstellt, mit H-Dateien verbunden und danach auf Speicherlecks überprüft. Wichtig zu erwähnen ist dabei, das ich das ganze mit gkt und glade gemacht habe. Nun habe ich velgrind verwendet, um zu schauen, ob ich evt Speicherlecks habe. Als Ergebnis bekam ich, das keine Speicherlecks gefunden wurden. Um das nochmal zu überprüfen habe ich auch fsanitize benutzt, wobei Speicherlecks von 85.000 Bytes herauskamen.

Jetzt ist meine Frage dazu, wie das sein kann. An sich habe ich immer free benutzt, wenn ich Speicher belegt habe (etwa mit malloc oder strdup) und um den Speicher der gtk_widgets sollte sich eigentlich glade kümmern (soweit ich das richtig gelesen habe). Ich habe auch am Ende meines Codes, nach gtk_main(); noch g_object_unref(builder); angegeben, um den speicher, den der builder belegt freizugeben.

Ich habe mir jetzt schonmal Gedanken dazu gemacht. In meinem Kopf würde es Sinn machen, das fsanitize den nicht erkennt, wenn Gtk den Speicher freigibt und deswegen so viele Lecks findet. Jedoch habe ich auch gelesen, das fsanitize eigentlich präziser als velgrind ist. Jetzt bin ich natürlich verwirrt und würde mich über eine Expertenmeinung freuen.

Anbei vielleicht noch: es ist eher ein kleines programm, welches nur materialen (aus einer txt-Datei) in ein gtk_tree_view einfügt, wo man nach einer Artikelnummer suche kann, einen Eintrag löschen kann und auch einen neuen erstellen kann. Deswegen kann ich mir auch schonmal gar nicht vorstellen, das 85.000Bytes als Speicheleck erkannt werden können.

Ich freue mich über jede Hilfe :)

Programmiersprache, sprache c

C Programm funktioniert nicht Richtig?

Es geht um folgenden Code:

#include <gtk/gtk.h>
#include <string.h>
// Globale Variablen für die UI-Elemente
GtkWidget *search_entry;
GtkWidget *treeview;
GtkListStore *list_store;
GtkTreeModel *filter_model;
// Beispiel-Lagerbestand
typedef struct {
  const gchar *artikelnummer;
  const gchar *name;
  int bestand;
} Lagerartikel;
// Beispielhafte Lagerartikel
Lagerartikel lager[] = {
  {"1001", "Laptop", 15},
  {"1002", "Maus", 50},
  {"1003", "Tastatur", 30},
  {"1004", "Monitor", 10},
  {"1005", "Drucker", 5},
  {"1006", "USB-Stick", 100}
};
const int lager_size = sizeof(lager) / sizeof(lager[0]);
// Filterfunktion für die Suche
static gboolean filter_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) {
  gchar *artikelnummer = NULL;
  gtk_tree_model_get(model, iter, 0, &artikelnummer, -1);
  if (artikelnummer == NULL) {
    return TRUE;
  }
  GtkWidget *search_entry = GTK_WIDGET(data);
  const gchar *search_text = gtk_entry_get_text(GTK_ENTRY(search_entry));
  if (search_text == NULL) {
    search_text = "";
  }
  gboolean visible = TRUE;
  if (strlen(search_text) > 0) {
    visible = g_strrstr(artikelnummer, search_text) != NULL;
  }
  g_free(artikelnummer);
  return visible;
}
// Aktualisiert den Filter, wenn sich der Suchtext ändert
static void on_search_changed(GtkSearchEntry *entry, gpointer user_data) {
  gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter_model));
}
// Erstellt die Lagerbestand-Tabelle
static void setup_treeview(GtkBuilder *builder) {
  treeview = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));
  // Spalten für die TreeView erstellen
  GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
  GtkTreeViewColumn *col1 = gtk_tree_view_column_new_with_attributes("Artikelnummer", renderer, "text", 0, NULL);
  GtkTreeViewColumn *col2 = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", 1, NULL);
  GtkTreeViewColumn *col3 = gtk_tree_view_column_new_with_attributes("Bestand", renderer, "text", 2, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), col1);
  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), col2);
  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), col3);
  // ListStore erstellen und Daten füllen
  list_store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
  for (int i = 0; i < lager_size; i++) {
    GtkTreeIter iter;
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter, 0, lager[i].artikelnummer, 1, lager[i].name, 2, lager[i].bestand, -1);
  }
  // Filtermodell erstellen
  filter_model = gtk_tree_model_filter_new(GTK_TREE_MODEL(list_store), NULL);
  gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter_model), filter_func, search_entry, NULL);
  gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), filter_model);
}
// Hauptfunktion
int main(int argc, char *argv[]) {
  gtk_init(&argc, &argv);
  // Glade-Datei laden
  GtkBuilder *builder = gtk_builder_new_from_file("part1.glade");
  // Widgets abrufen
  GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "main_window"));
  search_entry = GTK_WIDGET(gtk_builder_get_object(builder, "search_entry"));
  // Signal für die Suche
  g_signal_connect(search_entry, "search-changed", G_CALLBACK(on_search_changed), search_entry);
  g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  // Setup für die TreeView
  setup_treeview(builder);
  // Fenster anzeigen
  gtk_widget_show_all(window);
  gtk_main();
  return 0;
}

Ich benutze Glade um mit c ein interface zu erstelle.
Hier sollen die definierten Lagerartikel nach den Artikelnummern gesucht werden. Wenn man etwa 1002 eingibt bleibt nur 1002 übrig. wenn ich jetzt aber die 2 wegnehme, bleibt nur 1002 und 1003 übrig, obwohl alle angezeigt werden sollten.

Jetzt ist meine Frage, wie ich das beheben kann.
Auch ist folgendes: Bei 1003 zu 100 kommt 1003, 1004, 1005. Bei 1004 zu 100 kommt 1004, 1005, 1006, genau das gleiche bei 1005 und 1006. Nur bei 1001 zu 100 kommt alles

Programmiersprache, C (Programmiersprache)
Weitere Inhalte können nur Nutzer sehen, die bei uns eingeloggt sind.