首页 > 解决方案 > 内存泄漏 Valgrind 不报告,但代码使用了这么多内存

问题描述

我最近发布了一个关于在使用 Valgrind 运行时我的代码中遇到的分段错误问题,但是我已经摆脱了分段错误问题,现在代码正在运行,但是“吃掉”了这么多内存,这表明valgrind 不一定看到的某个地方的内存泄漏?我不确定。例如,它会在内核杀死我的进程之前运行到第 40 次迭代。

以前的帖子: Valgrind 的分段错误

如果我使用对代码的更正运行代码:(初始化我的数组并将数组的大小更改为足够大)

char save [16] = {0};
snprintf(save, 16,  "%d", saveNum);
const char *type = " .txt";
            
char Nfilename[16] = {0};
strcat(Nfilename, "N");
strcat(Nfilename, save);

char KEfilename[16] = {0};
strcat(KEfilename, "KE");
strcat(KEfilename, save);

char KIfilename[16] = {0};
strcat(KIfilename, "KI");
strcat(KIfilename, save);

char Pfilename[16] = {0};
strcat(Pfilename, "P");
strcat(Pfilename, save);

print2DArrf(Nfilename, N); 
print2DArrf(KEfilename, KE);
print2DArrf(KIfilename, KI);
print2DArrf(Pfilename, P);

这解决了我在每次精确迭代时遇到的分段错误问题。但是,如果我将代码运行几次迭代,我的计算机将耗尽 RAM,我尝试在 Mac 上使用活动内存监视器运行代码(因为 Valgrind 需要数天才能在调试模式下运行并且没有出现内存泄漏问题)和结果是代码在几分钟内达到 16GB !我确保释放所有东西,所以肯定发生了其他事情。

我想知道发生了什么,为什么它在代码中占用了这么多内存以及如何修复它?我想查看我的代码中的每个主要功能(如下所示)并分别运行每个功能以查明问题,但这似乎很乏味并且可能没有真正帮助。它实际上是内存泄漏吗?

这些是我希望单独运行以解决此“内存”问题的主要功能:

// calculate some values 
        convolution(Nk, KEk, Pek);
        Fourier3D(Pek, kb, Pek);

        
        convolution(Nk, KIk, Pik);
        Fourier3D(Pik, kb, Pik);
        
        Freqk(Nk, KIk,KEk , kb, eps0, mi, me, ri, rn, nn, Oci, Oce, e, nuink, nuiek, nuiik, nuenk, nueek, nueik, isigPk, NNk);
        
        dk(Nk, kx, dndxk);
        dk(Nk, ky, dndyk);

        calcPSk(dndxk, dndyk, Pik, Pek, nuink, nuiek, nuenk, nueik, isigPk, Oci, Oce, u, B, ksqu, potSourcek);

主要代码示例:

#include<math.h>
#include<stdio.h>
#include "Functions.h"
#include "fftw3.h"
#include <cstring>

int main(){         
    
    // Setting parameters 
    double frequency = 200.0;    
    double dt = 0.1;        
    double tend = 5000.; 
    double err_max = 1e-7;          

    int P_iter_max = 500;      

    int iter_max = tend / dt;
    int saveNumber = 1;

//Initialize Parameters 

double *N;
    N = (double*) fftw_malloc(nx*ny*sizeof(double));

fftw_complex *Nk;
    Nk = (fftw_complex*) fftw_malloc(nx*nyk*sizeof(fftw_complex)); 

double *KIk;
    KIk = (double*) fftw_malloc(nx*ny*sizeof(double));

double *KE;
    KE = (double*) fftw_malloc(nx*ny*sizeof(double));
    
fftw_complex *KEk;
    KEk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex)); 
    
    
double *P;
    P = (double*) fftw_malloc(nx*ny*sizeof(double));
    
    fftw_complex *Pk;
    Pk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex)); 

//Save I.Cs 

    int P_iter = Potk(invnk, dndxk, dndyk, Pk, PSk, kx, ky, ninvksq, err_max, P_iter_max);



    for (int iter = 0; iter < iter_max; iter++){

         // calculate some values 
        convolution(Nk, KEk, Pek);
        Fourier3D(Pek, kb, Pek);

        
        convolution(Nk, KIk, Pik);
        Fourier3D(Pik, kb, Pik);
        
        Freqk(Nk, KIk,KEk , kb, eps0, mi, me, ri, rn, nn, Oci, Oce, e, nuink, nuiek, nuiik, nuenk, nueek, nueik, isigPk, NNk);
        
        dk(Nk, kx, dndxk);
        dk(Nk, ky, dndyk);

        calcPSk(dndxk, dndyk, Pik, Pek, nuink, nuiek, nuenk, nueik, isigPk, Oci, Oce, u, B, ksqu, potSourcek);
    



         //Check for convergence

         // Save I.C loop

        P_iter = Pk(NNk, dndxk, dndyk, phik, potSourcek, kx, ky, ninvksqu, err_max, P_iter_max);
    } // seems to be the correct location of for loop end (see comment)
    double time[iter_max + 1];
    time[0] = 0;
    
    c2rfft(Nk, N);
    c2rfft(KEk, KE);    
    c2rfft(KIk, KI);
    c2rfft(Pk, P);
    
    char Ninitial[] = "N_initial.txt";
    char KEinitial[] = "KE_initial.txt";
    char KIinitial[] = "KI_initial.txt";
    char Pinitial[] = "P_initial.txt";
    

    print2DArrf(Ninitial, N);
    print2DArrf(KEinitial, KE);
    print2DArrf(KIinitial, KI);
    print2DArrf(Pinitial, P);
} // close of main() (??)

我真的很感激一些关于如何解决这个问题的见解。我是新手,我发现理解这个问题有些困难。

标签: c++memory-leaksvalgrindram

解决方案


确保从堆中释放()所有 malloc 的内存

double *N;
    N = (double*) fftw_malloc(nx*ny*sizeof(double));

fftw_complex *Nk;
    Nk = (fftw_complex*) fftw_malloc(nx*nyk*sizeof(fftw_complex)); 

double *KIk;
    KIk = (double*) fftw_malloc(nx*ny*sizeof(double));

double *KE;
    KE = (double*) fftw_malloc(nx*ny*sizeof(double));
    
fftw_complex *KEk;
    KEk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex)); 
    
    
double *P;
    P = (double*) fftw_malloc(nx*ny*sizeof(double));
    
    fftw_complex *Pk;
    Pk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex)); 


    .
    .
    .
    free(N);
    free(Nk);
    free(KIk);
    free(KE);
    free(KEk);
    free(P);
    free(Pk);

推荐阅读