[英]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.