如何释放所有mallocated键和值?

时间:2014-02-17 21:40:26

标签: c glib

修改

我像这样创建了gtree:

GTree* t = g_tree_new_full((GCompareDataFunc)g_ascii_strcasecmp,NULL,free_data,free_data);

我有自由功能:

void free_data (gpointer data)
{
  free (data);
}

我插入这样的东西:

int HoleInstrumentenListe(GTree *tree)
{
  printf("HoleInstrumentenListe\n");
  FILE * fp = fopen("cfg/InstrumentList_FULL.csv", "rb" );
  char * line = NULL;
  size_t len = 0;
  ssize_t read;
  int *pQotStatus;

  if (fp == NULL) {
    printf("Konnte Instrumentenliste nicht laden\n");
    exit(FAILLoadInstrumentList);
  }

  while ((read = getline(&line, &len, fp)) != -1)
  {
    char *p1;
    int  *p2 = malloc(sizeof (int));

    p1 = strtok(line, "|");
    *p2 = atoi(strtok(NULL, "|"));

    if ((pQotStatus = (int *) g_tree_lookup(tree, p1)) != NULL )
    {
       *p2 = (*pQotStatus | (1<<(*p2-1)));
    }
    else {
       *p2 = (1<<(*p2-1));
    }
    g_tree_insert(tree, (gpointer) g_strdup(p1), (gpointer)p2);
  }
  fclose(fp);
  return 1;
}

我像那样摧毁树:

g_tree_destroy (t);

我仍然有内存泄漏。

一些valgrind输出:

==4828== 1,024 bytes in 1 blocks are still reachable in loss record 4 of 260
==4828==    at 0x4A21370: malloc (vg_replace_malloc.c:291)
==4828==    by 0x4B5AA95: g_malloc (in /opt/gnome/lib64/libglib-2.0.so.0.800.6)
==4828==    by 0x4B5BC59: g_mem_chunk_alloc (in /opt/gnome/lib64/libglib-2.0.so.0.800.6)
==4828==    by 0x4B733D5: ??? (in /opt/gnome/lib64/libglib-2.0.so.0.800.6)
==4828==    by 0x4B73609: ??? (in /opt/gnome/lib64/libglib-2.0.so.0.800.6)
==4828==    by 0x4B735D6: ??? (in /opt/gnome/lib64/libglib-2.0.so.0.800.6)
==4828==    by 0x4B735D6: ??? (in /opt/gnome/lib64/libglib-2.0.so.0.800.6)
==4828==    by 0x4B73511: ??? (in /opt/gnome/lib64/libglib-2.0.so.0.800.6)
==4828==    by 0x4B73511: ??? (in /opt/gnome/lib64/libglib-2.0.so.0.800.6)
==4828==    by 0x4B736BA: g_tree_insert (in /opt/gnome/lib64/libglib-2.0.so.0.800.6)
==4828==    by 0x401037: HoleInstrumentenListe (unzipper_m.c:101)
==4828==    by 0x401879: main (unzipper_m.c:396)

第101行

g_tree_insert(tree, (gpointer) g_strdup(p1), (gpointer)p2);

1 个答案:

答案 0 :(得分:2)

对于上面的内容,无论如何都会泄露,因为您将密钥复制两次(strdup( g_strdup(p1)))。摆脱外部的罢工,所以你只有g_strdup(p1)

此时,您只需要g_free键和值,这不难做(您只需将g_free传递给key_destroy_func和value_destroy_func参数):

GTree* t = g_tree_new_full (key_compare_func, NULL, g_free, g_free);

但是,由于您的值是整数,因此您可以使用GINT_TO_POINTERGPOINTER_TO_INT来避免使用malloc。在这种情况下,你最终会得到这样的东西:

gint key_compare_func (gconstpointer a, gconstpointer b) {
  return g_strcmp0 ((const char*) a, (const char*) b);
}

int readFilec(GTree *tree)
{
  FILE * fp = fopen("cfg/InstrumentList_FULL.csv", "rb" );
  char * line = NULL;
  size_t len = 0;
  ssize_t read;
  GTree* t = g_tree_new_full (key_compare_func, NULL, g_free, NULL);

  if (fp == NULL)
  exit(EXIT_FAILURE);

  while ((read = getline(&line, &len, fp)) != -1)
  {
    char *p1;
    int  p2;
    printf("%s", line);
    p1 = strtok(line, "|");
    p2 = atoi(strtok(NULL, "|"));
    g_tree_insert(tree, (gpointer) g_strdup(p1), GINT_TO_POINTER(p2));
    //TrieAdd(&root, strdup(p1), p2);
    printf("-%s%d ", p1, p2);
  }

  //exit(EXIT_SUCCESS);

}