2014-10-15 16 views
1

다음 오류가 발생했습니다. glibc에서 valgrind의 출력이 C++에서 오류를 감지했습니다.

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

코드를 게시 할 수 있습니까? 아니면 적어도 그것의 parrt? – lisu

답변

2

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의를 사용하고 있다는 사실에서 유래 발생합니다. 여러 작업을 수행 한 후에 반올림 오류로 인해 double 값의 정확도가 떨어질 수 있으며 처음 계획했던 것보다 더 많은 단계를 실행하게됩니다.

Here's an example to help illustrate the issue. 이것은 정확도가 특정 숫자 cannot be represented as floating point values이기 때문에 발생합니다. 이 오류가 발생하는지 여부는 루프의 상위 값과 루프의 단계 크기에 따라 달라집니다.

2

valgrind 출력은 할당 된 메모리 블록 밖에있는 메모리 위치에 쓰고 있음을 알려주며 할당 및 불법적 인 액세스가 발생한 곳의 호출 스택을 제공합니다.

내 생각 엔 (게시 된 코드에 줄 번호를 추가 주시기 바랍니다) 위반 라인 Histogram.cpp:130이 라인이 때문이다

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

대부분의 아마 당신이 그 이상 반복하는 방식에 문제가 있습니다 정렬. 그 목적으로 double 값을 사용하고 있으며 반올림 오류로 인해 배열의 끝이 오버 슛하게됩니다.

는 예를 들어, 값 tbuck 조합 (해당 유형 어쨌든 무엇인지?)하고 tStep = tbuck/(double) tbuck2을 계산하지만 조건 tStep + tStep + ...(tbuck2 summands)... + tStep < tbuck 여전히 사실이다 있도록 tbuck2 있습니다.

, 예를 들어, 대체 당신은 오히려 배열을 반복 정수 변수를 사용한다

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

또한 루프 xy

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

유사하게 라운딩을 피하기 위해 오류 및 따라서 잘못된 배열 액세스.