C链接列表valgrind无效读取大小

我的链接列表和valgrind输出有问题。 这里没有进一步的说明是我的链表:

typedef struct Map map; struct Map { void *address; double free_time; map* next; }*map_list; 

使用虚拟头节点创建列表。 正如您所看到的,struct包含一个地址和一个空闲时间,我尝试将它们关联起来。

find_and_free函数中,我使用时间搜索此列表,如果此时间小于列表中存储的时间,则取消分配已保存的地址。 然后我也解除了列表节点的释放。

这是用于查找任何小于我传递的空闲时间的函数。 如果它更小,我释放存储到列表中的地址,然后调用delete_map_node函数也解除分配列表的节点。

 void find_and_free_address(map *root, double mtime) { map *current = root->next; assert(current); while(current) { if(current->free_time free_time); printf("The map contains an address that is time to free\n"); //free_allocated_address(&current->address); free(current->address); delete_map_node(map_list, current->free_time); //delete(map_list,current->free_time); //return next; } else { printf("there is nothing to free now\n"); } current = current->next; //FIRST ERROR } printf("THE MAP SIZE AFTER REMOVALS IS %d\n", map_size(map_list)); } 

这是delete_map_node函数

 map* delete_map_node(map *root,double ftime) { if (root==NULL) { return NULL; } //map *temporary; if (root->free_time == ftime) { map *temporary = root->next; free(root); //SECOND ERROR root = temporary; return temporary; } root->next = delete_map_node(root->next, ftime); //free(root->address); return root; } 

我知道这两个可以合并为一个function。

valgrind,报告没有内存泄漏或未初始化的值。 但是当我执行以下命令时:

 valgrind --tool=memcheck --leak-check=full --track-origins=yes -v ./a.out 

我得到以下输出:

 ==6807== Invalid read of size 4 ==6807== at 0x8049228: find_and_free_address (Map.c:123) ==6807== by 0x8048DA6: second_iteration (List.c:150) ==6807== by 0x8048C6B: first_iteration (List.c:113) ==6807== by 0x8048908: main (Fscanf.c:63) ==6807== Address 0x42005bc is 12 bytes inside a block of size 16 free'd ==6807== at 0x402AF3D: free (vg_replace_malloc.c:468) ==6807== by 0x804929F: delete_map_node (Map.c:142) ==6807== by 0x80492C1: delete_map_node (Map.c:147) ==6807== by 0x8049216: find_and_free_address (Map.c:113) ==6807== by 0x8048DA6: second_iteration (List.c:150) ==6807== by 0x8048C6B: first_iteration (List.c:113) ==6807== by 0x8048908: main (Fscanf.c:63) 

我可以看到错误是我在释放它们之后访问root->nextcurrent->next ,但我没有设法没有它。

你能建议我一个办法,摆脱这个错误吗?

我看到的一个问题是,在delete_map_node你释放了root (可能是从map_list传递的find_and_free_address ),但你实际上并没有改变map_list ,这意味着当delete_map_node返回map_list变量指向未分配的内存时。 之后访问map_list会导致未定义的行为

对此的简单解决方案是将delete_map_node的返回值分配给map_list

 map_list = delete_map_node(map_list, current->free_time); 

另外,当delete_map_node释放列表中currentfind_and_free_address函数中的节点时会发生什么? 然后current = current->next也会导致未定义的行为。