uthash删除和内存泄漏,valgrind

时间:2017-09-23 13:34:56

标签: c memory-leaks valgrind uthash

我对结构使用uthash哈希表实现。

我有两个哈希表,其中一个(代码中的 dataTable )在循环中收集一些信息,当它完成时,将一些数据保存在另一个哈希表中(即 stuffTable )。我的程序工作(至少有小文件)但是当我用valgrind检查时,它会发现第二个哈希表的内存泄漏( stuffTable )(但第一个表没有泄漏,尽管我释放了它以同样的方式)

    ==12075== Invalid read of size 8
    ==12075==    at 0x111CEE: deleteTable (myTest.c:1456)
    ==12075==    by 0x116AE6: getResults (myTest.c:1980)
    ==12075==    by 0x117E69: packetLoop (myTest.c:2350)
    ==12075==    by 0x1114C1: main (myTest.c:2872)
    ==12075==  Address 0x8335498 is 40 bytes inside a block of size 96 free'd
    ==12075==    at 0x4C2D16B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==12075==    by 0x111CE0: deleteTable (myTest.c:1458)
    ==12075==    by 0x116AE6: getResults (myTest.c:1980)
    ==12075==    by 0x117E69: packetLoop (myTest.c:2350)
    ==12075==    by 0x1114C1: main (myTest.c:2872)
    ==12075==  Block was alloc'd at
    ==12075==    at 0x4C2DF55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==12075==    by 0x112046: getStuffs (myTest.c:1475)
    ==12075==    by 0x116A75: getResults (myTest.c:1972)
    ==12075==    by 0x117E69: packetLoop (myTest.c:2350)
    ==12075==    by 0x1114C1: main (myTest.c:2872)

正如您所看到的,我只使用malloc来创建一个新节点,并且在我为其分配内存的stuff结构中没有其他数据结构。所以我不明白是什么导致内存泄漏。要删除哈希表,我使用标准程序,由uthash文档给出:

void delete_all() {
  struct my_struct *current_user, *tmp;

  HASH_ITER(hh, users, current_user, tmp) {
    HASH_DEL(users,current_user);  /* delete; users advances to next */
    free(current_user);            /* optional- if you want to free  */
  }
}

这是我的代码:

struct stuff {
      u_int32_t key;
      u_int32_t packets
      u_int32_t bytes;
      u_int32_t host;
      char name[16]; 
      UT_hash_handle hh;
    };

    struct stuff *myStuffTable = NULL;

    struct key_data {
      u_int32_t key;
      u_int32_t packets;
      u_int32_t bytes;
      u_int32_t count;
      struct triple top_host[A_SIZE];
      UT_hash_handle hh;
    };

    struct key_data *dataTable = NULL;

    struct triple {
      u_int32_t host;
      u_int32_t count;
      char proto[16];

    };

    static void deleteTable(struct stuff *dataTable) {
      struct stuff *current_key, *tmp;

      HASH_ITER(hh, dataTable, current_key, tmp) { //(myTest.c:1456)
        HASH_DEL(dataTable, current_key);
        free(current_key); //(myTest.c:1458)
      }
    }

    static void getStuffs(struct stuff **stuffTable, struct key_data *dataTable) {
      struct stuff *s;
      struct key_data *kd, *tmp;
      struct triple inf;


      HASH_ITER(hh, dataTable, kd, tmp) {
        s = (struct stuff *)malloc(sizeof(struct stuff)); //(myTest.c:1475)
        memset(s, 0, sizeof(struct stuff));

        s->key = kd->key;
        s->packets = kd->packets;
        s->bytes = kd->bytes;

        /* sort host array and take the first element */
        qsort(&kd->hosts[0], A_SIZE, sizeof(struct triple), triple_cmp);
        inf = kd->hosts[0];

        if(((inf.count > THRESHOLD) {
          s->host = inf.host;
          strncpy(s->name, inf.name, sizeof(s->name));
        }
        else
          s->host = 0;

        HASH_ADD_INT(*stuffTable, key, s);
      }

    }

    int main(){

            .....

            getStuffs(&myStuffTable, dataTable);
            deleteTable(myStuffTable);
    }

0 个答案:

没有答案