2014-02-28 3 views
0

이 작업 시도 중 ... GDB는 인덱스가 어떤 이유로 꺼져 있음을 나타냅니다. 두 가지 방법으로 정렬해야하는 주로 population (int) 및 name (string)을 포함하는 Record라는 하위 클래스의 벡터를 사용하고 있습니다. bt는 isSmaller() 함수의 'if'문인 27 행의 널 포인터를 나타냅니다. 이 함수는 동일한 프로그램의 삽입 정렬 코드에서는 완벽하게 작동하지만 병합 정렬에서는 작동하지 않으므로 병합 정렬 코드에 무엇이 잘못된 것인지 궁금합니다. 제발 조언. 알고리즘에 문제가 있습니까?Segfault C++에서 정렬 코드

BT는 다음을 반환 : 당신은 널 포인터를 가지고, 27, 즉 :

#0 0x0000000000403160 in CensusData::isSmaller (this=0x7fffffffdd10, type=0,  r1=0x609590, r2=0x0) at CensusDataSorts.cpp:27 
#1 0x0000000000403510 in CensusData::mergeIt (this=0x7fffffffdd10, type=0,  list=..., p=0, q=1, r=2) at CensusDataSorts.cpp:96 
#2 0x0000000000403347 in CensusData::mergeSortIt (this=0x7fffffffdd10,  type=0, list=..., p=0, r=2) at CensusDataSorts.cpp:70 
#3 0x0000000000403645 in CensusData::mergeSort (this=0x7fffffffdd10, type=0) at CensusDataSorts.cpp:113 
#4 0x0000000000401a50 in runMergeSorts (fp=...) at CensusSort.cpp:106 
#5 0x0000000000401e6f in main (argc=2, argv=0x7fffffffe068) at CensusSort.cpp:174 

코드 CensusDataSorts.cpp에서)

bool CensusData::isSmaller(int type, Record* r1, Record* r2) 
{ 
    if(type==POPULATION) 
    { 
     if(r1->population <= r2->population) 
      return true; 
    } 

    else if(type==NAME) 
    { 
     if(*(r1->city) <= *(r2->city)) 
      return true; 
    } 

    return false;   
} 

void CensusData::mergeSortIt(int type, vector<Record*>& list, int p, int r) 
{ 
    if(p < r) 
    { 
     int q = floor((p+r)/2); 
     mergeSortIt(type,list,p,q); 
     mergeSortIt(type,list,q+1,r); 
     mergeIt(type,list,p,q,r); 
    }   
}  

void CensusData::mergeIt(int type, vector<Record*>& list, int p, int q, int r) 
{ 
    int n1=q-p+1; 
    int n2=r-q; 
    int i,j; 

    vector<Record*> L(n1,0); 
    vector<Record*> R(n2,0); 

    for(i=0; i<n1; i++) 
     L[i]=list[p+i]; 

    for(j=0; j<n2; j++) 
     R[j]=list[q+j+1]; 

    i=0; 
    j=0; 

    for(int k=p; k<=r; k++) 
    { 
     if(isSmaller(type,L[i],R[j])) 
     { 
      list[k]=L[i]; 
      i++; 
     } 
     else 
     { 
      list[k]=R[j]; 
      j++; 
     } 
    } 
} 

void CensusData::mergeSort(int type) 
{ 
    mergeSortIt(type, data, 0, data.size()-1); 
} 
+0

GDB에서 이미 디버깅 중이므로 함수 호출 백 트레이스를 사용 하시겠습니까? 그리고 표시된 코드에서 충돌이 발생한 지점을 지적하십시오. 또한 충돌이 발생했을 때 인덱스뿐만 아니라 관련된 벡터의 크기도 추가하십시오. –

+0

call stack please .. – 51k

+0

GDB에서 bt 유형을 의미하고 출력을 게시 하시겠습니까? 프로그램 수신 신호 SIGSEGV, 세그먼트 오류. CensusData :: isSmaller에서 0x0000000000403160은 CensusDataSorts.cpp에서 (이 0x7fffffffdd10, 유형 = 0, R1 = 0x609590, R2 =이 0x0 =) : (R1-> 인구 <= r2-> 인구) – Prasad

답변

1

문제는 병합 기록을 다시 작성 방법입니다 당신의 세그 폴트.

+0

그것은 나에게 약간의 진전을 주었고 나는 새로운 코드에서 약간의 변경을했다 ... 목록 대신 [k ++]를 사용하여 마지막 2 개의 루프를 만들었고 [++ k] 목록을 사용했고 이제는 완벽하게 작동한다! 고맙습니다 xD – Prasad

0

R2 = 0x0으로 아래에 나타납니다.

return r1->population < r2->population; 

return *(r1->city) < *(r2->city); 

은 그렇지 않으면 이해가되지 않습니다 :

또한 비교를 변경합니다. 논리적으로 정확하려면 < = 가질 수 없습니다. 사실 나는 부적절한 비교 때문에 충돌을 분류하고있다. 여기

for(int k=p; k<=r; k++) 
{ 
    // Here i or j can be outside L/R bounds 
    if(isSmaller(type,L[i],R[j])) 
    { 
     list[k]=L[i]; 
     i++; 
    } 
    else 
    { 
     list[k]=R[j]; 
     j++; 
    } 
} 

버전 다시 작성 :

int k=p; 
for(; k<=r; k++) 
{ 
    if(isSmaller(type,L[i],R[j])) 
    { 
     list[k]=L[i]; 
     i++; 
     if (i == L.size()) 
      break; 
    } 
    else 
    { 
     list[k]=R[j]; 
     j++; 
     if (j == R.size()) 
      break; 
    } 
} 
for (; i < L.size(); ++i) 
    list[k++]=L[i]; 
for (; j < R.size(); ++j) 
    list[k++]=R[j]; 

나는 확실하지 않다 의도 한대로 프로그램 작업이 취하면,하지만 수정해야

+0

라인 (27)은 간단한 경우 기능 isSmaller()에서 위의 코드에서 조건 : \t \t 경우 (R1-> 인구 <= r2-> 인구) – Prasad

+0

예 중 하나는 R2는 널 포인터 것을 방지 할 필요하거나 포인터를 초기화해야 r2 제대로. 위의 짧은 답변을 위해 죄송합니다. – user2672165

+0

정확히 같은 isSmaller() 함수는 동일한 프로그램에서 삽입 정렬 코드로 완벽하게 작동합니다. 그래서 병합 정렬 코드가 무엇이 문제인지 궁금합니다. – Prasad