2014-07-07 3 views
0

Je reçois une erreur de fuite de mémoire de mon code:libre Double ou corruption: 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) 

Courir where gdb je reçois:

#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 

où 828 est la ligne de retour dans mon main() fonction. Le code en question est:

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] << " "; 
    } 
    } 
} 

Et la struct est allouée de manière statique:

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]; 
}; 

où:

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

Toute aide serait grandement appréciée. Je pensais que si une structure était allouée statiquement, alors l'appel

delete struct_name; 

supprimerait la référence. Merci pour l'aide!

MISE À JOUR:

Je couru valgrind et il m'a dit d'enlever le delete EKParms. J'ai enlevé la ligne delete EKParms et a couru à nouveau comme:

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

et la sortie je suis arrivé était:

==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) 

Cependant, quand je lance le programme normalement je reçois toujours la double erreur ou la corruption avant.

+0

Lancez votre programme sous 'valgrind --leak-check = full your_program'. Très probablement votre corruption de mémoire s'est produite ailleurs. –

+0

@ dandan78 Il y a un 'nouveau'. –

+0

@EitanT Oups, merci, manqué cela. – dandan78

Répondre

4

Le problème est probablement une corruption de mémoire. Vous avez un buggy #define PEAK_NUM. Besoins entre parenthèses:

#define PEAK_NUM (MEAN_PEAK_NUM_HIGH+MEAN_PEAK_NUM_LOW) 

Sans les parenthèses supplémentaires, par exemple, vous avez ceci:

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

Et qui est évidemment beaucoup moins que prévu, de sorte que votre fonction corrompt probablement la mémoire et tout peut arriver après .

Commencez par réparer cela! En outre, cela démontre pourquoi les macros sont mauvaises. Vous devez être très prudent lors de leur utilisation, et ils ont même parfois mordu même un programmeur expérimenté.


Même si cela est hors de la portée de la question, voici une façon de définir de manière plus sûre les constantes:

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

Bingo! Cela m'aurait pris pour toujours à remarquer ... merci! – ryan

Questions connexes