![](/img/trans.png)
[英]Sorting a Vector of a custom class with std::sort() causes a segmentation fault
[英]std::sort causes segmentation fault in operator<
我正在嘗試對 3D integer 向量( IntVec
)的列表( std::vector
)進行排序。 不知何故, std::sort
在IntVec
的operator<
中導致了分段錯誤。 這是我的代碼:
#include <iostream>
#include <algorithm>
#include <vector>
#include <fstream>
struct IntVec
{
public:
long x;
long y;
long z; // Using ints does not cause the Segmentation Fault ?!
friend bool operator<(const IntVec &lhs, const IntVec &rhs)
{
return (lhs.z < rhs.z) || // Segmentation Fault happens here
((lhs.z == rhs.z) && (lhs.y < rhs.y))
|| ((lhs.y == rhs.y) && (lhs.x < rhs.x));
}
};
int main(void)
{
std::vector<IntVec> vec;
const int N = 2178;
std::ifstream s("res.txt");
for (int i = 0; i < N; i++)
{
IntVec t;
s >> t.x;
s >> t.y;
s >> t.z;
vec.push_back(t);
}
// Using vec.begin() and vec.end() does not change anything
std::sort(vec.data(), vec.data() + vec.size());
}
我可以為您提供數據集; 但是,我首先想看看我的代碼中是否有一些重大的概念錯誤或我沒有看到的一些錯誤。 我發現問題是特定於該數據集的。 如果我遺漏一個條目,則不會發生 Segfault。 我認為這很奇怪,因為這樣的錯誤應該更明顯並且與 memory 管理有關。 另請注意,對x
、 y
和z
使用整數不會導致任何問題。
這是代碼的godbolt版本。
這是一個相關的 SO question 。 但是,我認為我的代碼沒有導致此錯誤的相同缺陷。 我認為我的排序關系是“嚴格<”。
您的操作員的邏輯被破壞(不滿足嚴格的弱排序要求)。 最后一個子句也需要一個lhs.z == rhs.z
否則, lhs.z
可能> rhs.z
但您仍然會得到肯定的結果,從而導致排序不一致。
標准庫算法讓您有責任做到這一點,打破由此產生的假設很容易導致混亂(閱讀:未定義的行為),例如分段錯誤。
想象一下實現中的注釋,說“此時,我們知道a
小於b
,所以我們不需要對b
執行任何范圍/邊界檢查”。 當a
意外大於b
時,缺少邊界檢查可能會導致錯誤的 memory 訪問。 然而,結果可能更加微妙,並導致奇怪的錯誤,因此正確處理很重要。
您可能希望考慮使用更短、更不容易出錯的方法來實現此排序:
return std::tie(lhs.z, lhs.y, lhs.x) < std::tie(rhs.z, rhs.y, rhs.x);
在元組上使用operator<
(這是std::tie
給你的)自動(並且正確!)為你執行字典分解。
在std::tie
的 cppreference 頁面上實際上有一個很好的例子,表明這是很常見的事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.