【问题标题】:Is not stack'd, malloc'd or (recently) free'd, when all the variables is used当所有变量都被使用时,不会被堆栈、malloc 或(最近)释放
【发布时间】:2014-05-21 18:45:27
【问题描述】:

当我调用这个函数时:

int within(struct key *node, int *value) {                      
  int length = len(node);                                       
  if ((value <= node[length-1].data) && (value >= node[0].data)) // Problematic line
    return 0;                                                   
  else if (value > node[length-1].data)                         
    return 1;                                                   
  else if (value < node[0].data)                                
    return -1;                                                  
}                                                               

Valgrind 引发此错误消息:

地址 0x51f60a0 没有被堆栈、malloc 或(最近)释放

valuenode 变量具有正确的值。使用所有变量。那里的内存管理有什么问题?请告诉我,如果 sn-p 没有清除情况。

【问题讨论】:

  • 可能您的len 函数返回的长度比实际数组长。
  • 调用者可能为node 提供了无效值。
  • @Dan: 或者它可能返回 0。
  • @l159 编译此代码时是否收到任何编译器错误/警告?
  • @rici,你是对的,问题出在stackoverflow.com/questions/3637079/…

标签: c memory-management valgrind


【解决方案1】:

消息Address 0x51f60a0 is not stack'd, malloc'd or (recently) free 通常只是较大的 Valgrind 错误消息的一部分。

这些 Valgrind 错误消息通常如下所示:

Invalid read of size 4
   at 0x40F6BBCC: (within /usr/lib/libpng.so.2.1.0.9)
   by 0x40F6B804: (within /usr/lib/libpng.so.2.1.0.9)
   by 0x40B07FF4: read_png_image__FP8QImageIO (kernel/qpngio.cpp:326)
   by 0x40AC751B: QImageIO::read() (kernel/qimage.cpp:3621)
   Address 0xBFFFF0E0 is not stack'd, malloc'd or free'd

Invalid read of size 8
   at 0x40060E: free_adj_list (main.c:9)
   by 0x400844: main (main.c:65)
 Address 0x4c1d170 is 16 bytes inside a block of size 24 free'd
   at 0x4A04D72: free (vg_replace_malloc.c:325)
   by 0x400609: free_adj_list (main.c:8)
   by 0x400844: main (main.c:65)

如何阅读这些错误信息

消息的第一部分指出出了什么问题(“Invalid read of size 4”表示您尝试从不应访问的内存地址读取),然后是发生错误的回溯。

回溯后面是有关您尝试访问的内存地址的详细信息。 Valgrind 通过查看地址是否为:

  • 就在您有权访问的内存部分之外(因此您的程序执行了buffer overrun)。示例消息为Address 0x1002772ac is 4 bytes after a block of size 12 alloc'd
  • 在一块之前被释放的内存中(所以你的程序used memory after it was freed);例如:Address 0x4c1d170 is 16 bytes inside a block of size 24 free'd

这些消息之后是第二个回溯,指示您在哪里分配或释放了所提到的内存。

但是Address 0x51f60a0 is not stack'd, malloc'd or (recently) free'd 的消息意味着 Valgrind 无法猜出你的意图。您尝试访问 0x51f60a0 处的内存,但该地址最近没有被释放,并且不在您分配的内存的任何其他部分附近。因此,您可以合理地确定这种情况下的错误既不是缓冲区溢出也不是 use-after-free 错误。

如何调试这样的错误

因此我们可以假设 0x51f60a0 或多或少是“随机”内存地址。我可以想到这主要有两个可能的原因:

  • 您取消引用的指针包含一些未初始化的值;在这种情况下,您还应该从 Valgrind 收到 Use of uninitialised value 错误消息
  • 您取消引用了一个根本不打算用作指针的值 - 例如。该值实际上可能是您程序中某些不相关计算的结果,并且您以某种方式将该值写入了稍后使用的指针

除此之外,当然还有可能错误实际上是某些缓冲区溢出或 use-after-free 但 Valgrind 未能检测到它。

如何在你的程序中调试这个错误

我认为缩小问题范围的一种方法是在 Valgrind with GDB 中启动应用程序,以找出究竟是什么内存访问导致了错误(node 坏了吗?node[length-1] 坏了吗?node[0]坏的?)。然后找出糟糕的价值是如何出现的。

【讨论】:

    【解决方案2】:

    您的比较应该是
    *value &lt;= node[length-1].data
    不是
    value &lt;= node[length-1].data

    IOW,您在 value 变量之前缺少星号。

    【讨论】:

    • 这是真的,但我不认为这是valgrind 会抱怨的那种错误。
    • 关于 valgrind 的 IDk,但它是 UB 对不指向同一个对象的两个指针进行指针比较,所以这将是一个有用的报告。
    • 如果这确实是问题所在,那么int *int 的不兼容比较就会出现编译错误。
    【解决方案3】:

    是什么导致了我的“未堆叠、malloc 或(最近)释放”的问题。我希望这对像我这样的搜索引擎在这里指导的人有用。

    在我的例子中,我分配了一个大小为 585 的堆数组 p。但后来我尝试在 733~1300 的索引范围内访问 p。 valgrind 刚刚展示了这条信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-13
      • 1970-01-01
      • 1970-01-01
      • 2023-02-23
      • 2020-04-07
      • 1970-01-01
      • 2018-10-12
      • 1970-01-01
      相关资源
      最近更新 更多