我收到以下错误。
*** glibc detected *** ./bin/final: malloc(): memory corruption: 0x0000000000baaf20 ***
所以在谷歌上搜索后,我发现了valgrind,并在我的代码上运行了它,但我无法理解它产生的输出。我做错了什么?
==22297== Memcheck, a memory error detector
==22297== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==22297== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==22297== Command: ./bin/final
==22297==
xxj-00_2-057.pngnew.jpg 0
h ere1
h ere2
h ere1
h ere2
h ere1
==22297== Invalid write of size 8
==22297== at 0x40D6DE: Histogram::resample(int, int, int, std::vector<double, std::allocator<double> >&) (Histogram.cpp:130)
==22297== by 0x409860: Descriptor::calc(int, int, std::vector<bool, std::allocator<bool> >&) (Descriptor.cpp:100)
==22297== by 0x4035FF: main (db.cpp:44)
==22297== Address 0x11ebe2a0 is 0 bytes after a block of size 3,456 alloc'd
==22297== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22297== by 0x40A85F: std::vector<double, std::allocator<double> >::_M_default_append(unsigned long) (new_allocator.h:92)
==22297== by 0x40D75A: Histogram::resample(int, int, int, std::vector<double, std::allocator<double> >&) (stl_vector.h:592)
==22297== by 0x409860: Descriptor::calc(int, int, std::vector<bool, std::allocator<bool> >&) (Descriptor.cpp:100)
==22297== by 0x4035FF: main (db.cpp:44)
==22297==
--22297-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--22297-- si_code=80; Faulting address: 0x0; sp: 0x402bbee00
valgrind: the 'impossible' happened:
Killed by fatal signal
==22297== at 0x38058236: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==22297== by 0x38021ADC: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==22297== by 0x38021CCD: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==22297== by 0x380902A7: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==22297== by 0x3809F7D5: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable
==22297== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22297== by 0x40A85F: std::vector<double, std::allocator<double> >::_M_default_append(unsigned long) (new_allocator.h:92)
==22297== by 0x409D8C: Descriptor::calc(int, int, std::vector<bool, std::allocator<bool> >&) (stl_vector.h:592)
==22297== by 0x4035FF: main (db.cpp:44)
代码很大,但我已经在这里发布了相关部分。
void Descriptor::calc(int patchX,int patchY,vector<bool> &desc){
double valRange=patchSize*histogramRange;
Histogram histogram(-valRange,valRange,xbuck,-valRange,valRange,ybuck,-M_PI,M_PI,tbuck);
double minGradient=0;
vector<double> vals;
int patchBottom = patchY+patchSize;
int patchRight = patchX+patchSize;
int centralx = patchX+patchSize/2, centraly = patchY+patchSize/2;
for(int i=patchX;i<patchRight;i++){
for(int j=patchY;j<patchBottom;j++){
if(FUN(norMagnitude,i,j,double) < minPixVal)
continue;
double xp = i-centralx, yp = j-centraly;
double cos_t = cos(FUN(orientation,i,j,double));
double sin_t = sin(FUN(orientation,i,j,double));
double xpPrime = xp*cos_t - yp*sin_t;
double ypPrime = xp*sin_t + yp*cos_t;
histogram.increment(xpPrime,ypPrime,FUN(orientation,i,j,double),FUN(norMagnitude,i,j,double));
minGradient++;
}
}
if(minGradient < patchSize*patchSize*minimumEdge) //if atleast 60*60*0.01 pixel are not more than minPixVal then blank patch
return;
//Mat patch= norMagnitude(Rect(patchY,patchX,patchBottom-patchY,patchRight-patchX));
//namedWindow("k",CV_WINDOW_NORMAL);
//imshow("k",patch);
histogram.blur(sigma1,sigma2);
//histogram.show();
histogram.resample(xbuck2,ybuck2,tbuck2,vals);
int hist_size=xbuck2*ybuck2*tbuck2;
vector<double> arr;
arr.resize(hist_size);
cout<<arr.size()<<" "<<vals.size()<<endl;
copy(vals.begin(),vals.end(),arr.begin());
sort(arr.begin(),arr.end());
cout<<"h"<<endl;
double histTh = arr[(int)(hist_size*(1-threshold))];
for(int i=0;i<hist_size;i++){
if(vals[i]>histTh)
desc.push_back(1);
else
desc.push_back(0);
}
}
void Histogram::resample(int xbuck2,int ybuck2,int tbuck2,vector<double>& vals){
vals.resize(tbuck2*xbuck2*ybuck2);
int i = 0;
double tStep = tbuck/(double)tbuck2;
double yStep = ybuck/(double)ybuck2;
double xStep = xbuck/(double)xbuck2;
for(double t = 0; t < tbuck; t += tStep) {
for(double y = 0; y < ybuck; y += yStep) {
for(double x = 0; x < xbuck; x += xStep) {
vals[i]=(bFinalValue(x, y, t));
i++;
}
}
}
}
Valgrind官方文档中有一节介绍如何解释MemCheck的输出
我建议你从这里开始:http://valgrind.org/docs/manual/quick-start.html#quick-start.interpret
在您的情况下,错误Invalid write of size 8
表示您正在向越界内存位置写入。错误发生在Descriptor.cpp
线路100
等调用的Histogram.cpp
线路130
。
这个错误源于您在Histogram::resample
函数中使用double
s作为for循环迭代器的事实。在多次操作后,由于舍入错误,双倍值的准确性可能会降低,最终执行的步骤会比最初计划的要多。
这里有一个例子来帮助说明这个问题。这是因为某些数字不能以100%的精度表示为浮点值。是否遇到此错误将取决于循环的上限值以及循环的步长。
valgrind输出告诉您正在向分配的内存块外部的内存位置进行写入,并向您显示发生分配和无效访问的调用堆栈。
我的猜测(请随意在您发布的代码中添加行号)是,违规的Histogram.cpp:130
行是行
vals[i]=(bFinalValue(x, y, t));
最有可能的是,对该数组进行迭代的方式存在问题。为此,您使用的是double
值,舍入误差会使您超出数组的末尾。
例如,您有一个值tbuck
(它的类型是什么?)和tbuck2
的组合,这样尽管您计算了tStep = tbuck / (double) tbuck2
,条件tStep + tStep + ...(tbuck2 summands)... + tStep < tbuck
仍然为真。
您应该使用整数变量来迭代数组,例如,替换
for(double t = 0; t < tbuck; t += tStep) {
带有
for (int it = 0; it < tbuck2; ++it) {
double t = it * tStep;
以及类似地针对CCD_ 14和CCD_。