简体   繁体   English

C ++:std :: sort使用带有自定义谓词的已销毁对象?

[英]C++: std::sort using already destroyed object with custom predicate?

I'm having a very odd problem with some code using std::sort. 我在使用std :: sort的某些代码中遇到了一个非常奇怪的问题。 If I replace std::sort by stable_sort the problem goes away. 如果我用stable_sort替换std :: sort,问题就解决了。

class Entry
{
public:
    Entry() : _date(0), _time(0), _size(0) {}
    Entry(unsigned int d, unsigned int t, unsigned int s) : _date(d), _time(t), _size(s) {}
    ~Entry() {_size=0xfffffffe;}

    unsigned int _date, _time, _size;

};

void initialise(std::vector<Entry> &vec)
    vec.push_back(Entry(0x3f92, 0x9326, 0x1ae));
    vec.push_back(Entry(0x3f92, 0x9326, 0x8a54));
   //....  + a large number of other entries
}

static bool predicate(const Entry &e1, const Entry &e2)
{
    // Sort by date and time, then size
    if (e1._date < e2._date )
        return true;
    if (e1._time < e2._time )
        return true;

    return e1._size < e2._size;
}

int main (int argc, char * const argv[]) {
    using namespace std;
    vector<Entry> vec;
    initialise(vec);
    sort(vec.begin(), vec.end(), predicate);

    vector<Entry>::iterator iter;
    for (iter=vec.begin(); iter!=vec.end(); ++iter)
        cout << iter->_date << ", " << iter->_time <<
                  ", 0x" << hex << iter->_size << endl;

    return 0;
}

The idea is that I sort the data first by date and time then by size. 我的想法是我先按日期和时间对数据进行排序,然后再按大小对数据进行排序。 However, depending on the data in the vector, I will end up with 0xfffffffe in the size printed out at the end for the first object, indicating that a destroyed object has been accessed, or a seg fault during the sort. 但是,根据向量中的数据,我将得到第一个对象末尾打印出的大小为0xfffffffe,这表明已访问了损坏的对象,或在排序过程中出现了段错误。

(Xcode 3.2.4 - 64 bit intel target) (Xcode 3.2.4-64位Intel目标)

Any ideas anyone?? 有任何想法吗? I suspect it has something to do with my predicate, but I can't see for the life of me what it is....!! 我怀疑这与我的谓词有关,但是我看不出它是什么...。 This page seems to refer to the same problem: 该页面似乎涉及到相同的问题:

http://schneide.wordpress.com/2010/11/01/bug-hunting-fun-with-stdsort/ http://schneide.wordpress.com/2010/11/01/bug-hunting-fun-with-stdsort/

but the reason he gives (that the predicate needs to define a strict weak ordering) seems to be satisfied here... 但是他给出的理由(谓词需要定义严格的弱序)似乎在这里得到了满足...

Your predicate does not satisfy strict weak ordering criteria. 您的谓词不满足严格弱排序标准。 Look at your function and ask yourself, what happens if e1's date comes after e2, but e1's time comes before e2? 查看您的函数并问自己,如果e1的日期 e2 之后 ,但是e1的时间 e2 之前,该怎么办?

I think what your predicate really should be is something like this: 我认为您的谓词真正应该是这样的:

static bool predicate(const Entry &e1, const Entry &e2)
{
    // Sort by date and time, then size
    return e1._date < e2._date || 
      (e1._date == e2._date && 
        (e1._time < e2._time || 
          (e1._time == e2._time && e1._size < e2._size)));
}

What you wrote - if e1._date>e2._date , the first condition will be false, but the second may still be true and the function will still claim that e1<e2 which is probably not what you want. 您编写的内容-如果e1._date>e2._date ,则第一个条件为false,但第二个条件仍为true,并且该函数仍会声明e1<e2可能不是您想要的。

Your code needs to be: 您的代码必须是:

static bool predicate(const Entry &e1, const Entry &e2)
{
    // Sort by date and time, then size
    if (e1._date != e2._date )
        return e1._data < e2._date;
    if (e1._time != e2._time )
        return e1._time < e2._time;
    return e1._size < e2._size;
}

If e2's date is after e1, then your version treats goes on to compare the time and size. 如果e2的日期在e1之后,则您的版本将继续比较时间和大小。 This is not what you want. 这不是您想要的。 This eventually confuses std::sort because if you swap e1 and e2 you will not get a consistent answer. 最终使std :: sort混乱,因为如果交换e1和e2,将不会得到一致的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM