【问题标题】:Different memory leaks in different hardware architecture不同硬件架构中的不同内存泄漏
【发布时间】:2010-12-08 20:50:00
【问题描述】:

这些天我正在处理 C 代码中的内存泄漏。我很惊讶地看到不同硬件架构中的不同内存泄漏。

以下是 valgrind 在 64 位架构中展示的泄漏摘要:

                LEAK SUMMARY:
      ==4064==    definitely lost: 1,600,192 bytes in 7 blocks
      ==4064==    indirectly lost: 0 bytes in 0 blocks
      ==4064==      possibly lost: 0 bytes in 0 blocks
      ==4064==    still reachable: 3,217,416 bytes in 2,155 blocks
      ==4064==         suppressed: 0 bytes in 0 blocks
      ==4064== Reachable blocks (those to which a pointer was found) are not shown. 
      ==4064== To see them, rerun with: --leak-check=full --show-reachable=yes
      ==4064== 
      ==4064== For counts of detected and suppressed errors, rerun with: -v
       ==4064== ERROR SUMMARY: 7 errors from 7 contexts (suppressed: 4 from 4)

以下是32位架构

     LEAK SUMMARY:
    ==29607==    definitely lost: 1,600,048 bytes in 4 blocks .
    ==29607==    indirectly lost: 456 bytes in 33 blocks.
    ==29607==      possibly lost: 0 bytes in 0 blocks.
    ==29607==    still reachable: 96 bytes in 12 blocks.
    ==29607==         suppressed: 0 bytes in 0 blocks.
    ==29607== Reachable blocks (those to which a pointer was found) are not shown.
    ==29607== To see them, rerun with: --show-reachable=yes

这可能是什么原因。

【问题讨论】:

  • 输出是正常退出的程序?如果它在失败时存在,它可能会在不同的地方失败。由于崩溃通常与内存管理有很大关系,它可能会在每个架构之前或之后崩溃一点,因此差异很大。另请注意,64 位通常比 32 位使用更多的内存(即指针大小等)
  • 这是否意味着如果我能够设法防止任何架构中的内存泄漏,那么它将适用于两种架构?
  • 正确的程序不会泄漏:)

标签: c memory memory-management valgrind


【解决方案1】:

好吧,我不知道确切的细节,但是如果您泄漏一些基于某种类型的大小的数据,那么与 32 位相比,64 位的泄漏将导致更多的字节数位。

例如,如果你泄露了这条数据:

// arr holds an array of 10 pointers
int *arr = malloc(10 * sizeof(int *));

在 64 位(与 32 位相比)上泄漏会更大,因为 int * 的大小取决于平台。

【讨论】:

    【解决方案2】:

    也许您的 64 位机器上的库中存在一些错误?

    或者,您的某些代码可能会将指针转换为 32 位整数并返回,从而造成混乱。

    【讨论】:

      【解决方案3】:

      如果您遇到数组溢出或通过无效指针写入数据之类的问题,您可以预期不同机器上的内存布局会有所不同。所以如果你这样做:

      void * foo(void) {
           char str[100];
           void * p = malloc(100);
           memset(str, 0, 111);
           /* ... more code ... */
           return p;
      }
      

      然后你可以想象 str 和 p 都在堆栈上。它们的布局顺序可能不同,以及可能在堆栈上分配多少额外的字节来填充它们,因此 memset 长度的错误可能会丢失对新分配内存的引用,也可能不会.取决于许多其他事情,valgrind 可能会或可能不会注意到 memset 错误,但我需要使用一个易于理解的简单案例。

      这可能与正在发生的事情相似,也可能不相似,但我认为它表明了可能发生的事情的类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-23
        • 2021-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-29
        • 2012-11-25
        相关资源
        最近更新 更多