2014-07-07 154 views
0

因此,我從我的代碼獲得了內存泄漏錯誤:雙人免費或損壞:C++

*** glibc detected *** ./KalmanFiltering: double free or corruption (!prev): 0x00000000015af7b0 *** 
======= Backtrace: ========= 
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7f0897395b96] 
./KalmanFiltering[0x40654d] 
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f089733876d] 
./KalmanFiltering[0x4012b9] 
======= Memory map: ======== 
00400000-00415000 r-xp 00000000 00:15 6312794       /home/iggy/Dropbox/Documents/Research_Work/SimpleHealth/KalmanFilter/KalmanFilter_C++/cmpfit-1.2/KalmanFiltering 
00614000-00615000 r--p 00014000 00:15 6312794       /home/iggy/Dropbox/Documents/Research_Work/SimpleHealth/KalmanFilter/KalmanFilter_C++/cmpfit-1.2/KalmanFiltering 
00615000-00616000 rw-p 00015000 00:15 6312794       /home/iggy/Dropbox/Documents/Research_Work/SimpleHealth/KalmanFilter/KalmanFilter_C++/cmpfit-1.2/KalmanFiltering 
015ae000-01641000 rw-p 00000000 00:00 0         [heap] 
7f0897317000-7f08974cc000 r-xp 00000000 08:01 421630      /lib/x86_64-linux-gnu/libc-2.15.so 
7f08974cc000-7f08976cc000 ---p 001b5000 08:01 421630      /lib/x86_64-linux-gnu/libc-2.15.so 
7f08976cc000-7f08976d0000 r--p 001b5000 08:01 421630      /lib/x86_64-linux-gnu/libc-2.15.so 
7f08976d0000-7f08976d2000 rw-p 001b9000 08:01 421630      /lib/x86_64-linux-gnu/libc-2.15.so 
7f08976d2000-7f08976d7000 rw-p 00000000 00:00 0 
7f08976d7000-7f08976ec000 r-xp 00000000 08:01 395568      /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f08976ec000-7f08978eb000 ---p 00015000 08:01 395568      /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f08978eb000-7f08978ec000 r--p 00014000 08:01 395568      /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f08978ec000-7f08978ed000 rw-p 00015000 08:01 395568      /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f08978ed000-7f08979e8000 r-xp 00000000 08:01 422139      /lib/x86_64-linux-gnu/libm-2.15.so 
7f08979e8000-7f0897be7000 ---p 000fb000 08:01 422139      /lib/x86_64-linux-gnu/libm-2.15.so 
7f0897be7000-7f0897be8000 r--p 000fa000 08:01 422139      /lib/x86_64-linux-gnu/libm-2.15.so 
7f0897be8000-7f0897be9000 rw-p 000fb000 08:01 422139      /lib/x86_64-linux-gnu/libm-2.15.so 
7f0897be9000-7f0897ccb000 r-xp 00000000 08:01 531352      /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16 
7f0897ccb000-7f0897eca000 ---p 000e2000 08:01 531352      /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16 
7f0897eca000-7f0897ed2000 r--p 000e1000 08:01 531352      /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16 
7f0897ed2000-7f0897ed4000 rw-p 000e9000 08:01 531352      /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16 
7f0897ed4000-7f0897ee9000 rw-p 00000000 00:00 0 
7f0897ee9000-7f0897f0b000 r-xp 00000000 08:01 422388      /lib/x86_64-linux-gnu/ld-2.15.so 
7f08980a3000-7f08980ea000 rw-p 00000000 00:00 0 
7f0898107000-7f089810b000 rw-p 00000000 00:00 0 
7f089810b000-7f089810c000 r--p 00022000 08:01 422388      /lib/x86_64-linux-gnu/ld-2.15.so 
7f089810c000-7f089810e000 rw-p 00023000 08:01 422388      /lib/x86_64-linux-gnu/ld-2.15.so 
7fffc58ae000-7fffc58cf000 rw-p 00000000 00:00 0       [stack] 
7fffc59af000-7fffc59b0000 r-xp 00000000 00:00 0       [vdso] 
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 
Aborted (core dumped) 

運行在gdb where我得到:

#0 0x00007ffff723e425 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 
#1 0x00007ffff7241b8b in __GI_abort() at abort.c:91 
#2 0x00007ffff727c39e in __libc_message (do_abort=2, fmt=0x7ffff7386748 "*** glibc detected *** %s: %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:201 
#3 0x00007ffff7286b96 in malloc_printerr (action=3, str=0x7ffff7386858 "double free or corruption (!prev)", ptr=<optimized out>) at malloc.c:5039 
#4 0x000000000040654d in main (argc=6, argv=0x7fffffffe0c8) at KalmanFiltering.cpp:828 

,其中828是在返回行我main()功能。 有問題的代碼是:

int main(){ 
    ... 
    EKSmoothParams *EKParams = new EKSmoothParams; 
    prepareSmoother(optPar, ECGsd, peaks, phase, x, fs, EKParams); 

    delete EKParams; 

    return 0; 
} 

void prepareSmoother(vector<double> optPar, vector<double> ECGsd, vector<double> peaks, vector<double> phase, vector<double> x, double fs, EKSmoothParams *params){ 
    const int N = PEAK_NUM; // number of Gaussian kernels                               
    vector<int> JJ; 
    JJ.reserve(peaks.size()); 
    for(int i = 0; i < peaks.size(); i++){ 
    if(peaks.at(i) != 0) 
     JJ.push_back(i); 
    } 
    vector<double> fm; // heart-rate                                    
    fm.reserve(JJ.size()-1); 
    for(int i = 0; i < JJ.size()-1; i++){ 
    fm.push_back(fs/(JJ.at(i+1)-JJ.at(i))); 
    } 
    vector<double> twoPiFm = fm; 
    for(int i = 0; i < fm.size(); i++) 
    twoPiFm[i] = 2*PI*fm.at(i); 

    double w = calculateMean(twoPiFm);   // average heart-rate in rads.                         
    double wsd = sd2(twoPiFm);  // heart-rate standard deviation in rads.                          

    params->X0[0][0] = 1.0; 
    params->X0[0][1] = -PI; 
    params->X0[1][0] = 1.0; 
    params->X0[1][1] = 0.0; 

    params->P0[0][0] = pow(2*PI,2); 
    params->P0[0][1] = 0.0; 
    params->P0[1][0] = 2.0; 
    params->P0[1][1] = 10*pow(findAbsMax(x),2.0); 

    vector<double> diagonal(3*N+2, 0.0); 
    for(int i = 0; i < N; i++) 
    diagonal[i] = pow(0.1*optPar.at(i),2.0); 
    for(int i = N; i < 3*N; i++) 
    diagonal[i] = pow(0.5,2.0); 
    diagonal[3*N] = pow(wsd,2.0); 
    vector<double>::const_iterator first = ECGsd.begin(); 
    vector<double>::const_iterator last = ECGsd.begin() + round(ECGsd.size()/10.0); 
    vector<double> ECGsdPartial(first, last); 
    displayVector(ECGsd); 
    diagonal[3*N+1] = pow(0.05*calculateMean(ECGsdPartial), 2.0); 

    for(int i = 0; i < diagonal.size(); i++) 
    params->Q[i][i] = diagonal[i]; 

    params->R[0][0] = pow(w/fs,2)/12.0;; 
    params->R[0][1] = 0.0; 
    params->R[1][0] = 0.0; 
    params->R[1][1] = pow(calculateMean(ECGsdPartial), 2.0); 

    for(int i = 0; i < optPar.size(); i++){ 
    params->wMean[i] = optPar.at(i); 
    params->inits[i] = optPar.at(i); 
    } 
    params->wMean[N*3] = w; 
    params->wMean[N*3+1] = 0; 
    params->inits[N*3] = w; 
    params->inits[N*3+1] = fs; 

    params->vMean[0] = 0.0; 
    params->vMean[1] = 0.0; 

    params->inovWlen = round(0.5*fs+0.5); 
    params->tau = 0; 
    params->gamma = 1; 
    params->rAdaptWlen = round(fs/2.0 + 0.5); 
    params->flag = 1; 

    for(int i = 0; i < 2; i++){ 
    for(int j = 0; j < 2; j++){ 
     cout << params->R[i][j] << " "; 
    } 
    } 
} 

而且結構是靜態分配:

struct EKSmoothParams { 
    int tau; 
    int gamma; 
    int flag; 
    int inovWlen; 
    int rAdaptWlen; 

    double wMean[3*PEAK_NUM+2]; 
    double vMean[2]; 
    double inits[3*PEAK_NUM+2]; 

    double X0[2][2]; 
    double P0[2][2]; 
    double Q[3*PEAK_NUM+2][3*PEAK_NUM+2]; 
    double R[2][2]; 
}; 

其中:

#define MEAN_PEAK_NUM_HIGH 3 
#define MEAN_PEAK_NUM_LOW 3 
#define PEAK_NUM MEAN_PEAK_NUM_HIGH+MEAN_PEAK_NUM_LOW 

任何幫助將不勝感激。我認爲如果一個結構是靜態分配的,那麼只能調用

delete struct_name; 

會刪除引用。謝謝您的幫助!

UPDATE:

所以我跑Valgrind的,它告訴我要刪除delete EKParms。我刪除了delete EKParms線,並再次運行它:

valgrind --leak-check=full ./KalmanFiltering x.txt pphase.txt phase.txt opt.txt peaks.txt 

和輸出我得到的是:

==32755== Memcheck, a memory error detector 
==32755== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. 
==32755== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info 
==32755== Command: ./KalmanFiltering x.txt pphase.txt phase.txt opt.txt peaks.txt 
==32755== 
0.117777 0.102793 0.0911142 0.107277 0.109 0.126729 0.115012 0.109627 0.131102 0.100467 0.0822639 0.122442 0.0908527 0.116644 0.108093 0.104796 0.12665 0.102979 0.0999146 0.119981 0.107912 0.122379 0.113098 0.0889197 0.106954 0.101472 0.125473 0.107778 0.13228 0.10528 0.11511 0.107965 0.0961817 0.125068 0.12075 0.110846 0.120621 0.132226 0.106999 0.114672 0.0997654 0.104048 0.117857 0.105461 0.127318 0.11103 0.134415 0.12594 0.126633 0.116603 0.109422 0.117 0.130797 0.112808 0.113414 0.0951991 0.112291 0.109693 0.118444 0.104215 0.124635 0.0993083 0.122034 0.122363 0.12139 0.0969221 0.108173 0.109436 0.115881 0.118631 0.0968963 0.104841 0.118923 0.10789 0.108117 0.119053 0.115187 0.119369 0.089593 0.0893818 0.127805 0.109007 0.108001 0.128517 0.105524 0.117847 0.127699 0.101618 0.113646 0.112389 0.114674 0.108706 0.117413 0.119509 0.110195 0.116943 0.132244 0.108374 0.117175 0.114302 0.113753 0.127603 0.104102 0.112583 0.110015 0.102419 0.122587 0.104333 0.122883 0.129287 0.129104 0.10733 0.11312 0.125945 0.119181 0.128817 0.129468 0.114589 0.146289 0.135648 0.118936 0.146207 0.160105 0.167322 0.16074 0.140913 0.153806 0.178517 0.215381 0.251905 0.163988 0.137749 0.107549 0.121755 0.121141 0.0867208 0.103768 0.130058 0.142986 0.115026 0.12086 0.12443 0.122726 0.110762 0.125137 0.126337 0.0953488 0.10774 0.112677 0.116888 0.115948 0.104844 0.114403 0.121069 0.110119 0.0980817 0.109335 0.104094 0.10667 0.118813 0.123157 0.11163 0.105456 0.103909 0.112385 0.126633 0.123956 0.108601 0.113358 0.0971531 0.123609 0.116769 0.130958 0.103691 0.114814 0.116871 0.12273 0.116116 0.118833 0.11895 0.100572 0.128861 0.110058 0.121104 0.122787 0.122287 0.114645 0.12352 0.122679 0.121228 0.116913 0.128488 0.111704 0.102892 0.119502 0.113897 0.144082 0.132502 0.115685 0.145348 0.137543 0.12479 0.132752 0.137675 0.144116 0.127518 0.146219 0.152045 0.123085 0.152635 0.153129 0.159488 0.139282 0.150634 0.119596 0.1195 0.127458 0.109524 0.106355 0.116666 0.114375 0.104727 0.0978894 0.0941401 0.11789 0.11224 0.110342 0.106331 0.104715 0.0991576 0.116447 0.0908483 0.11542 0.105876 0.0955746 0.120995 0.125514 0.130953 0.12472 0.118668 0.118989 0.106662 0.117213 0.111635 0.106181 0.11708 0.101769 0.10301 0.112952 0.104064 
3.31532e-06 0 0 0.0118791 
==32755== 
==32755== HEAP SUMMARY: 
==32755==  in use at exit: 0 bytes in 0 blocks 
==32755== total heap usage: 61,624 allocs, 61,624 frees, 6,091,874 bytes allocated 
==32755== 
==32755== All heap blocks were freed -- no leaks are possible 
==32755== 
==32755== For counts of detected and suppressed errors, rerun with: -v 
==32755== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) 

然而,當我運行該程序通常我仍然得到雙重釋放或腐敗誤差之前。

+0

下'的valgrind --leak檢查=全運行程序your_program'。很可能你的記憶腐敗發生在別的地方。 –

+0

@ dandan78有一個'新'。 –

+0

@EitanT哎呀,謝謝,錯過了。 – dandan78

回答

4

問題可能是內存損壞。你有錯誤#define PEAK_NUM。需要括號:

#define PEAK_NUM (MEAN_PEAK_NUM_HIGH+MEAN_PEAK_NUM_LOW) 

沒有這些額外的括號,你比如這個:

double Q[3*MEAN_PEAK_NUM_HIGH+MEAN_PEAK_NUM_LOW+2][3*MEAN_PEAK_NUM_HIGH+MEAN_PEAK_NUM_LOW+2]; 

而這顯然比預期的要少得多,所以你的功能可能破壞內存,任何事情都有可能之後發生的。

開始修復!另外,這也證明了爲什麼宏是邪惡的。使用它們時必須非常小心,即使是經驗豐富的程序員,他們偶爾也會遇到。


儘管這是出了問題的範圍,這裏的更安全地定義常量一個方式:

enum { 
    MEAN_PEAK_NUM_HIGH = 3, 
    MEAN_PEAK_NUM_LOW = 3, 
    PEAK_NUM = MEAN_PEAK_NUM_HIGH + MEAN_PEAK_NUM_LOW 
}; 
+0

賓果!那會讓我永遠注意......謝謝! – ryan