簡體   English   中英

C ++中的Segfault合並排序代碼

[英]Segfault in C++ merge sort code

試圖使其正常工作。GDB似乎表明索引可能由於某種原因而關閉。 我正在使用一個稱為Record的子類的向量,該向量主要包含總體(int)和名稱(string),需要同時對其進行排序。 bt指示第27行的空指針,這是isSmaller()函數中的'if'語句。 此功能與同一程序中的插入排序代碼完美地兼容,但與合並排序不同,因此,我想知道合並排序代碼有什么問題。 請指教。 算法有問題嗎?

bt返回以下內容:

#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

代碼出現在下面

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

問題是您重寫合並記錄的方式:

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];

我不確定這是否會使您的程序按預期工作,但是它應該可以解決您的段錯誤。

r2 = 0x0)在CensusDataSorts.cpp:27,即您有一個空指針。

還將比較更改為:

return r1->population < r2->population;

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

否則,這是沒有意義的。 您不能使用<=使其在邏輯上正確。 實際上,由於比較不正確,我自己發生了排序崩潰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM