因此,我的代码出现内存泄漏错误:
*** 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是my
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;
会删除引用。谢谢你的帮助!
更新:
所以我运行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)
但是,当我正常运行程序时,仍然会像以前一样出现双重释放或损坏错误。
最佳答案
问题可能是内存损坏。你的车#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
};
关于c++ - 双重释放或腐败:C++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24604181/