使用OpenMP进行编译会导致内存泄漏 [英] Compiling with OpenMP results in a memory leak

查看:215
本文介绍了使用OpenMP进行编译会导致内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据valgrind的说法,当使用OpenMP编译简单的hello-world程序时,可能会导致内存泄漏。这没有意义,因为hello-world程序不会有意使用任何OpenMP功能。

假设下面的程序名为 hi.c 并根据
$编译b $ b

$ gcc -o hi hi.c



GCC版本4.8.3

  #include< stdio.h> 

int main(void)
{
printf(hi\\\
);
返回1;

$ / code>

我们应该期望从valgrind得到一份泄漏报告来证实这一点:没有泄漏。我的观察结果与这一假设一致:

  $ valgrind --tool = memcheck ./hi 
== 13064 == Memcheck,一个内存错误检测器
== 13064 == Julian Seward等人版权所有(C)2002-2013,以及GNU GPL'd。
== 13064 ==使用Valgrind-3.9.0和LibVEX;使用-h获取版权信息
== 13064 ==命令:./hi
== 13064 ==
hi
== 13064 ==
== 13064 ==总结:
== 13064 ==在退出时使用:0字节在0块
== 13064 ==总堆使用情况:0分配,0释放,0字节分配
== 13064 ==
== 13064 ==所有堆块都被释放 - 没有泄漏是可能的
== 13064 ==
== 13064 ==用于检测和压制的计数错误,重新运行:-v
== 13064 ==错误总结:0错误来自0上下文(压制:2从2)

我也希望在与其他标志编译后收到相同的报告。然而,这种情况并非如此。当我使用 -fopenmp 标志进行编译时,我观察到内存泄漏

$ gcc -fopenmp -o hi hi.c

  $ valgrind --tool = memcheck ./hi 
== 13084 == Memcheck,一个内存错误检测器
== 13084 == Julian Seward等人的版权(C)2002-2013和GNU GPL'd。
== 13084 ==使用Valgrind-3.9.0和LibVEX;使用-h获取版权信息
== 13084 ==命令:./hi
== 13084 ==
hi
== 13084 ==
== 13084 ==总结:
== 13084 ==在退出时使用:8个字节在1个块中
== 13084 ==总堆使用情况:2个分配,1个空闲,32,824字节分配
== 13084 ==
== 13084 == LEAK SUMMARY:
== 13084 ==绝对丢失:0字节0字节
== 13084 ==间接丢失:0字节0块
== 13084 ==可能丢失:0块中的0字节
== 13084 ==仍然可以访问:1块中有8个字节
== 13084 ==抑制:0字节0块
== 13084 ==重新运行--leak-check = full查看泄漏内存的详细信息
== 13084 ==
== 13084 ==用于检测和抑制的计数错误,重新运行:-v
== 13084 ==错误总结:0错误来自0个上下文(被抑制:2从2)

有谁知道为什么使用OpenMP编译导致内存泄漏?虽然这个特定的程序没有调用OpenMP,但我想确保在最终使用它时正确处理内存。

解决方案

p> valgrind报告没有描述内存泄漏。仍然可以在程序出口处分配堆内存。



很可能您的编译器的openmp实现将全局变量插入到您的程序中,并导致它作为部分动态分配(即在 main())之前。


According to valgrind, I can induce a memory leak when compiling a simple hello-world program with OpenMP. This doesn't make sense, because the hello-world program does not intentionally use any OpenMP functionality.

Suppose the program below is named hi.c and compiled according to

$ gcc -o hi hi.c

GCC version 4.8.3

#include <stdio.h>

int main( void )
{
  printf( "hi\n" );
  return 1;
}

We should expect a leak report from valgrind to verify the obvious: there are no leaks. My observations agree with this hypothesis:

$ valgrind --tool=memcheck ./hi
==13064== Memcheck, a memory error detector
==13064== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==13064== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==13064== Command: ./hi
==13064== 
hi
==13064== 
==13064== HEAP SUMMARY:
==13064==     in use at exit: 0 bytes in 0 blocks
==13064==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==13064== 
==13064== All heap blocks were freed -- no leaks are possible
==13064== 
==13064== For counts of detected and suppressed errors, rerun with: -v
==13064== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

I would also expect to receive the same report after compiling with other flags. However, this is not the case. When I compile with the -fopenmp flag, I observe a memory leak

$ gcc -fopenmp -o hi hi.c

$ valgrind --tool=memcheck ./hi
==13084== Memcheck, a memory error detector
==13084== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==13084== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==13084== Command: ./hi
==13084== 
hi
==13084== 
==13084== HEAP SUMMARY:
==13084==     in use at exit: 8 bytes in 1 blocks
==13084==   total heap usage: 2 allocs, 1 frees, 32,824 bytes allocated
==13084== 
==13084== LEAK SUMMARY:
==13084==    definitely lost: 0 bytes in 0 blocks
==13084==    indirectly lost: 0 bytes in 0 blocks
==13084==      possibly lost: 0 bytes in 0 blocks
==13084==    still reachable: 8 bytes in 1 blocks
==13084==         suppressed: 0 bytes in 0 blocks
==13084== Rerun with --leak-check=full to see details of leaked memory
==13084== 
==13084== For counts of detected and suppressed errors, rerun with: -v
==13084== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

Does anyone understand why compiling with OpenMP causes this memory leak? Although this particular program does not invoke OpenMP, I want to be sure that I am handling memory properly when I do eventually use it.

解决方案

That valgrind report does not depict a memory leak. The heap memory remaining allocated at program exit is still reachable.

Very likely your compiler's openmp implementation injects a global variable into your program, and causes it to be dynamically allocated as part of program startup (i.e. before main()).

这篇关于使用OpenMP进行编译会导致内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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