我在c中创建了一个通用映射(使用clion),在我的nodeDestroy函数中,我调用了一个通用的freeing函数来释放节点列表的密钥和数据。 nodeDestroy:
void nodeDestroy(Node node) {
Node current = node;
Node next;
while (current != NULL) {
next = current->next;
current->free_key(current->key);
current->key = NULL;
current->free_data(current->data);
current->data = NULL;
free(current);
current = next;
}
node = NULL;
}
这是节点struct:
struct node_t{
MapKeyElement key;
MapDataElement data;
Node next;
copyMapKeyElements copy_key;
copyMapDataElements copy_data;
freeMapKeyElements free_key;
freeMapDataElements free_data;
};
我用整数指针测试地图(每个节点的数据和键都是int *),这是整数释放函数:
static void freeInt(MapKeyElement e) {
free((int*)e);
}
free_key和free_data在nodeCreate中给我,两者都设置为freeInt。当我在valgrind中检查这个时,不会释放每个节点的密钥和数据。任何想法?
所以我注意到只有在使用另一个函数时才会出现问题:mapPut。我将添加理解代码所需的函数实现以及之前未添加的一些内容。
/** Data element data type for map container */
typedef void* MapDataElement;
/** Key element data type for map container */
typedef void* MapKeyElement;
/** Type of function for copying a data element of the map */
typedef MapDataElement(*copyMapDataElements)(MapDataElement);
/** Type of function for copying a key element of the map */
typedef MapKeyElement(*copyMapKeyElements)(MapKeyElement);
/** Type of function for deallocating a data element of the map */
typedef void(*freeMapDataElements)(MapDataElement);
/** Type of function for deallocating a key element of the map */
typedef void(*freeMapKeyElements)(MapKeyElement);
struct Map_t{
Node iterator;
copyMapKeyElements copy_key;
copyMapDataElements copy_data;
freeMapKeyElements free_key;
freeMapDataElements free_data;
compareMapKeyElements compare_keys;
Node head;
};
bool mapContains(Map map, MapKeyElement element){
if (map == NULL || element == NULL){
return false;
}
mapGetFirst(map);
if (getKey(map->iterator) != NULL && map->compare_keys(getKey(map->iterator)
, element) == 0){
return true;
}
while (mapGetNext(map) != NULL){
if (getKey(map->iterator) != NULL &&
map->compare_keys(getKey(map->iterator), element) == 0){
return true;
}
}
return false;
}
MapResult mapPut(Map map, MapKeyElement keyElement, MapDataElement dataElement){
if (map == NULL || keyElement == NULL || dataElement == NULL){
return MAP_NULL_ARGUMENT;
}
MapDataElement data_copy = map->copy_data(dataElement);
if (data_copy == NULL){
return MAP_OUT_OF_MEMORY;
}
MapResult result = MAP_SUCCESS;
if (mapContains(map,keyElement) == true){
mapGetFirst(map);
while (map->iterator != NULL){
if (map->compare_keys(keyElement, getKey(map->iterator)) == 0) {
map->free_data(getData(map->iterator));
setData(map->iterator, data_copy);
return setIterator(map, MAP_SUCCESS);
}
map->iterator = getNext(map->iterator);
}
}
mapGetFirst(map);
MapKeyElement key_copy = map->copy_key(keyElement);
if (key_copy == NULL){
map->free_data(data_copy);
return setIterator(map, MAP_OUT_OF_MEMORY);
}
if (getKey(map->iterator) == NULL){
setKey(map->iterator, key_copy);
setData(map->iterator, data_copy);
return setIterator(map, MAP_SUCCESS);
}
Node new_node = nodeCreate(map->copy_data, map->copy_key,
map->free_data, map->free_key, &result);
if (result == MAP_OUT_OF_MEMORY) {
map->free_data(data_copy);
map->free_key(key_copy);
return setIterator(map, MAP_OUT_OF_MEMORY);
}
setData(new_node, data_copy);
setKey(new_node, key_copy);
if (map->compare_keys(key_copy, getKey(map->iterator)) < 0){
setNext(new_node,map->iterator);
map->head = new_node;
return setIterator(map, MAP_SUCCESS);
}
while(map->iterator != NULL) {
if (getNext(map->iterator) == NULL){
setNext(map->iterator, new_node);
break;
}
if (map->compare_keys(key_copy, getKey(getNext(map->iterator))) < 0){
Node temp_next = getNext(map->iterator);
setNext(map->iterator, new_node);
setNext(new_node, temp_next);
break;
}
map->iterator = getNext(map->iterator);
}
return setIterator(map, MAP_SUCCESS);
}
static MapResult setIterator(Map map, MapResult result){
map->iterator = NULL;
return result;
}
MapKeyElement mapGetFirst(Map map){
if (map == NULL){
return NULL;
}
map->iterator = map->head;
return getKey(map->head);
}