user3747190
user3747190

Reputation: 1707

Output of valgrind on glibc detected error in C++

I was getting following error.

 *** glibc detected *** ./bin/final: malloc(): memory corruption: 0x0000000000baaf20 ***

So after googling it, I found about valgrind and run it on my code, but I am not able to understand the output produce by it. What I am doing wrong?

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

Code is very large but i have posted here the relevant part.

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

Upvotes: 1

Views: 673

Answers (2)

Mr. Llama
Mr. Llama

Reputation: 20909

The Valgrind official documentation contains a section on how to interpret MemCheck's output.
I would suggest that you start there: http://valgrind.org/docs/manual/quick-start.html#quick-start.interpret

In your case, the error Invalid write of size 8 means that you're writing to an out of bounds memory location. The error occurs in Histogram.cpp line 130 which was called by Descriptor.cpp line 100, etc.


The error stems from that fact that you're using doubles as your for-loop iterators in the Histogram::resample function. After multiple operations, the accuracy of the double value may degrade due to rounding errors and you'll end up executing more steps than you had initially planned.

Here's an example to help illustrate the issue. This occurs because certain numbers cannot be represented as floating point values with 100% accuracy. Whether or not you run into this error will depend on your loop's upper values as well as your loop's step size.

Upvotes: 2

Christoph Freundl
Christoph Freundl

Reputation: 627

The valgrind output tells you that are writing to a memory location which is outside the allocated memory block, and it presents you both the callstacks where the allocation and where the invalid access took place.

My guess (please feel free to add line numbers to your posted code) is that the offending line Histogram.cpp:130 is the line

vals[i]=(bFinalValue(x, y, t));

and most probably there is a problem with the way you are iterating over that array. You are using double values for that purpose, and rounding errors make you overshoot the array's end.

For example, you have a combination of values tbuck (what is its type anyway?) and tbuck2 such that though you compute tStep = tbuck / (double) tbuck2 the condition tStep + tStep + ...(tbuck2 summands)... + tStep < tbuck is still true.

You should rather use integer variables to iterate over the array, for example, replace

for(double t = 0; t < tbuck; t += tStep) {

with

for (int it = 0; it < tbuck2; ++it) {
    double t = it * tStep;

and also the loops for x and y similarly in order to avoid the rounding errors and therefore the invalid array access.

Upvotes: 2

Related Questions