C 链表 valgrind 大小读取无效 [英] C Linked List valgrind Invalid Read of Size

查看:25
本文介绍了C 链表 valgrind 大小读取无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的链接列表和 valgrind 输出有问题.不用多说了,这里是我的链表:

I have a problem with my Linked List and the valgrind output. Without further adieu here is my linked list:

typedef struct Map map;

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

列表是使用虚拟头节点创建的.如您所见,该结构体包含一个地址和一个空闲时间,我尝试将它们关联起来.

The list is created using a dummy head node. As you can see, the struct holds an address and a free time, which I try to associate them.

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

In the find_and_free function I search this list using a time and if this time is smaller than the one stored in the list, I deallocate the saved address. And then I deallocate the list node as well.

该函数用于查找任何比我经过的空闲时间还小的空闲时间.如果它更小,我释放存储到列表中的地址,然后调用delete_map_node函数也释放列表的节点.

This is the function used to find any free time that is smaller than the one I am passing. If it is smaller, I free the address stored to the list, and then call the delete_map_node function to also deallocate the node of the list.

void find_and_free_address(map *root, double mtime)
{
    map *current = root->next;
    assert(current);
    while(current)
    {
        if(current->free_time < mtime)
        {

            printf("there is something to FREE now
");
            printf("the time to check for free is %lf and the maps free time is %lf
", mtime,current->free_time);
            printf("The map contains an address that is time to free
");
            //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
");
        }

        current = current->next; //FIRST ERROR
    }
    printf("THE MAP SIZE AFTER REMOVALS IS %d
", 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;
}

我知道这两者只能组合为一个功能.

I am aware that those two can be combined to only one function.

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

valgrind, reports no memory leaks or uninitialized values. However when I execute the following command:

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,但我没有设法没有它.

I can see that the error is that I access root->next and current->next after I have freed them, but I have not managed to do without it.

你能给我建议一种方法来摆脱这个错误吗?

Can you suggest me a way, to get rid of this error?

推荐答案

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

One problem that I see is that in delete_map_node you free root (which might be map_list passed from find_and_free_address), but you don't actually change map_list which means that when delete_map_node returns the map_list variable points to unallocated memory. Accessing map_list afterwards leads to undefined behavior.

解决这个问题的简单方法是将delete_map_node的返回值赋给map_list:

The simple solution to this is to assign the return value of delete_map_node to map_list:

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

此外,当delete_map_node 释放find_and_free_address 函数中current 列表中的节点时会发生什么?那么 current = current->next 也会导致未定义的行为.

Also, what happens when delete_map_node frees the node in the list that is current in the find_and_free_address function? Then current = current->next will also lead to undefined behavior.

这篇关于C 链表 valgrind 大小读取无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆