通用自由函数不会在通用映射中释放通用值

时间:2018-05-20 14:59:59

标签: c memory-management

我在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);
}

0 个答案:

没有答案