C 链表 valgrind 大小读取无效

2023-12-19

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

typedef struct Map map;

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

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

In the 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 < mtime)
        {

            printf("there is something to FREE now\n");
            printf("the time to check for free is %lf and the maps free time is %lf\n", mtime,current->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;
}

我知道这两个功能只能合并为一个功能。

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->next and current->next在我释放了它们之后,但我还是无法摆脱它。

你能建议我一种方法来消除这个错误吗?


我看到的一个问题是delete_map_node你自由了root(这可能是map_listfind_and_free_address),但你实际上并没有改变map_list这意味着当delete_map_node返回map_list变量指向未分配的内存。访问map_list之后导致未定义的行为 http://en.wikipedia.org/wiki/Undefined_behavior.

解决这个问题的简单方法是分配返回值delete_map_node to map_list:

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

另外,当delete_map_node释放列表中的节点current in the find_and_free_address功能?然后current = current->next也会导致未定义的行为。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 链表 valgrind 大小读取无效 的相关文章

  • 如何在MVVM中管理多个窗口

    我知道有几个与此类似的问题 但我还没有找到明确的答案 我正在尝试深入研究 MVVM 并尽可能保持纯粹 但不确定如何在坚持模式的同时启动 关闭窗口 我最初的想法是向 ViewModel 发送数据绑定命令 触发代码来启动一个新视图 然后通过 X
  • 无法使用已与其底层 RCW 分离的 COM 对象。在 oledb 中

    我收到此错误 但我不知道我做错了什么 下面的代码在backrgroundworker中 将异常详细信息复制到剪贴板 System Runtime InteropServices InvalidComObjectException 未处理 通
  • 是否可以强制 XMLWriter 将元素写入单引号中?

    这是我的代码 var ptFirstName tboxFirstName Text writer WriteAttributeString first ptFirstName 请注意 即使我使用 ptFirstName 也会以双引号结束 p
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • C# 中的递归自定义配置

    我正在尝试创建一个遵循以下递归结构的自定义配置部分
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • for循环中计数器变量的范围是多少?

    我在 Visual Studio 2008 中收到以下错误 Error 1 A local variable named i cannot be declared in this scope because it would give a
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a
  • 防止索引超出范围错误

    我想编写对某些条件的检查 而不必使用 try catch 并且我想避免出现 Index Out of Range 错误的可能性 if array Element 0 Object Length gt 0 array Element 1 Ob
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐