rxi / map

A type-safe hash map implementation for C

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Custom type data

zxyAcmen opened this issue · comments

Hello, I learned your map code,After applying for space on the heap, calling map ﹣ deinit ﹣ will not release the empty space applied by the user. It is not very clear about this. If you want to request, email: zxyacmen@163.com, QQ: 8101309. If you can, can you direct me.

中文:您好,我学习了你的map代码,请问自定数据类型在堆上申请空间后,调用map_deinit_后不会释放用户自己申请的空吧,对这块不是很清楚,想请求下, 邮箱:zxyacmen@163.com,qq:8101309 如果可以的话能否直接指点下。

Hi zxyAcmen,

Declaration: I am not the author nor the maintainer of this project.
The map stores data as a Hash table. The value passed into map_set() will be copied and saved to the map. Internally, map calls map_newnode to allocate space, thus the behaviour can be found in map_newnode(). As you can seem, the passing value is copied using memcpy() and saved as node->value To answer your question, the memory allocated for the passing value won't be freed when map_deinit() is called. Only the copy in the node will be freed,

static map_node_t *map_newnode(const char *key, void *value, int vsize) {
  map_node_t *node;
  int ksize = strlen(key) + 1;
  int voffset = ksize + ((sizeof(void*) - ksize) % sizeof(void*));
  node = malloc(sizeof(*node) + voffset + vsize);
  if (!node) return NULL;
  memcpy(node + 1, key, ksize);
  node->hash = map_hash(key);
  node->value = ((char*) (node + 1)) + voffset;
  memcpy(node->value, value, vsize);
  return node;
}

声明:我不是该项目的作者和维护者。

这个Map通过哈希表来储存数据。当你把key和value传进 map_set()的时候,传进去的Value会被使用memcpy(node->value, value, vsize);复制一份存在node->value中。所以当你调用map_deinit()的时候,堆上的空间并不会被释放,只有Node中复制的那一份会被释放。

commented

@zxyAcmen

// 正确的使用方法如下,如果涉及到动态分配的数据类型,不建议使用此库。
// map_get(&mMan, key) 所取得的数据,与最初数据是两码事,而且数据指向有耦合。

#define CRTDBG_MAP_ALLOC

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <time.h>
#include <math.h>
#include <crtdbg.h>

#include <map/map.h>

struct Man
{
char* name;
};
typedef map_t(struct Man *) map_man_t;

int main(int argc, char* argv[], char* env[])
{
map_man_t mMan;

struct Man* manHg = NULL;

struct Man* manHerry = NULL;

struct Man** man_pp = NULL;

char* key;

map_iter_t iter;

_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

map_init(&mMan);

manHg = malloc(sizeof(struct Man));
manHg->name = malloc(100);
strcpy(manHg->name, "hg");

manHerry = malloc(sizeof(struct Man));
manHerry->name = malloc(100);
strcpy(manHerry->name, "herry");


map_set(&mMan, "hg", manHg);
map_set(&mMan, "herry", manHerry);

iter = map_iter(&mMan);
while ((key = map_next(&mMan, &iter)))
{
	man_pp = map_get(&mMan, key);

	printf("key:%s --- name:%s\n", key, (*man_pp)->name);
}



free(manHg->name);
free(manHerry->name);

free(manHg);
free(manHerry);

map_deinit(&mMan);

return 0;

}