簡體   English   中英

類對象向量上的sort()給出分段錯誤

[英]sort() on a vector of class objects gives segmentation fault

我正面臨這個棘手的問題,這使我毫無頭緒,也無法弄清這個問題。 以下是問題陳述。

共有100個團隊參加比賽(編號1至100),試圖解決9個問題。 團隊可能無法解決任何問題,在這種情況下total_solved問題和total_time將為零。 為了簡便起見,我將靜態向量的大小保持為100。該name存儲團隊編號(1到100)。 我使用active標志來知道一個團隊至少提交了1個解決方案(甚至是錯誤的)。

這是班級team

class team
{
public:
        int total_solved;
        int time[9];
        int total_time;
        bool solved[9];
        bool active;
        int name;

        team()
        {
                total_solved = total_time = 0;
                active = false;
                name = -1;
                for(int i=0;i<9;i++)
                {
                        solved[i] = false;
                        time[i] = 0;
                }
        }
};

這是向量:

for(int i=0;i<100;i++)
{
    record.push_back(new team());
}

稍后,我將填寫有關團隊的數據。 這是與這些團隊相對應的數據轉儲:

                cout << "Dumping the data\n";
                for(auto it=record.begin();it!=record.end();it++)
                {
                        cout << (*it)->name << " " << (*it)->total_solved << " " << (*it)->total_time << " " << ((*it)->active?'Y':'N') << endl;
                }
                cout << "That's all\n";

Dumping the data
-1 0 0 N
2 0 0 Y
-1 0 0 N
-1 0 0 N
5 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
24 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
34 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
41 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
45 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
58 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
62 0 0 Y
-1 0 0 N
64 0 0 Y
-1 0 0 N
-1 0 0 N
67 0 0 Y
-1 0 0 N
69 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
78 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
That's all

您會看到在這種特定情況下,沒有團隊可以解決任何問題。 而且有些團隊不活躍(未提交任何解決方案, name為-1或active為false表示該解決方案)。 當我嘗試對這100個團隊數據進行排序時,發生崩潰。 排序標准是團隊必須在最短的時間內解決最大的問題。 如果有平局,我們將根據團隊編號進行排序,而忽略不活動的團隊。

bool compare(team *t1, team *t2)
{
        if(t1->total_solved != t2->total_solved)
                return t1->total_solved > t2->total_solved;
        if(t1->total_time != t2->total_time)
                return t1->total_time < t2->total_time;
        return t1->active;
}

sort(record.begin(),record.end(),compare);

我通過gdb分析,得到以下信息:

Program received signal SIGSEGV, Segmentation fault.
0x00005555555552d0 in compare (t1=0x55555576fec0, t2=0x411) at 10258.cpp:33
33              if(t1->total_solved != t2->total_solved)

t2肯定會獲得無效的指針,但我想知道為什么嗎?

編輯

這是可編譯的版本: https : //ideone.com/bcnmE0(帶有示例輸入)。

您的比較功能不正確。 如果第一個參數“小於”第二個參數,則比較函數應返回true。 但是,如果t1->active為true,則您的返回true(在所有其他條件相同的情況下)。 這意味着對於兩個相等的團隊,您的函數可能返回true(如果兩個團隊的active均為true)。 不正確的比較功能可能會導致排序算法崩潰。 試試這個

bool compare(team *t1, team *t2)
{
        if(t1->total_solved != t2->total_solved)
                return t1->total_solved > t2->total_solved;
        if(t1->total_time != t2->total_time)
                return t1->total_time < t2->total_time;
        return t1->active > t2->active;
}

或這個

        return t1->active < t2->active;

無論哪種方式,對於兩個相等的團隊,您都返回false。

如前所述,您需要使比較功能滿足Compare的要求。 除此之外,當其他字段比較相等時,您的比較功能未考慮團隊名稱。 我從您的示例@ ideone中獲取了一些信息,並修復了一些錯誤,從而制作了一個MCVE:

#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>
#include <array>

class team {
public:
    int total_solved;
    std::array<int, 9> time;
    int total_time;
    std::array<bool, 9> solved;
    bool active;
    int name;

    team(int Name) :
        total_solved{0},
        time{},
        total_time{0},
        solved{},
        active{false},
        name(Name)
    {}

    inline bool operator<(team const& t2) const {
        if(total_solved != t2.total_solved)
            return total_solved > t2.total_solved;
        if(total_time != t2.total_time)
            return total_time < t2.total_time;
        // return t1->active;          // bug
        if(active != t2.active)        // bug-fix
            return active > t2.active; //   -"-
        // the below was specified as the last sorting criteria
        // but wasn't included in your actual code:
        return name < t2.name;
    }

    friend std::ostream& operator<<(std::ostream&, const team&);
};

std::ostream& operator<<(std::ostream& os, const team& t) {
    os << t.name << " " << t.total_solved << " "
       << t.total_time << " " << (t.active?"Y":"N") << "\n";
    return os;
}

int main() {
    // bug-fix: making sure the teams are deleted using std::unique_ptr
    std::vector<std::unique_ptr<team>> record;

    for(int i=1; i<=100; ++i)
        record.emplace_back(new team(i));

    for(auto contestant : {41,67,34,2,69,24,78,58,62,64,5,45})
        record[contestant-1]->active = true;

    std::cout << "Dumping the data\n";
    for(auto& t : record) std::cout << *t;

    std::sort(record.begin(), record.end(),
        [](std::unique_ptr<team> const& a, std::unique_ptr<team> const& b) {
            return *a < *b;
        }
    );

    std::cout << "After sort\n";
    for(auto& t : record) std::cout << *t;
}

暫無
暫無

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

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