c++ - std::sort 过火了

标签 c++ algorithm sorting

我正在尝试使用谓词函数对对象 vector 进行排序,但遇到了一些段错误...

我有一个类Itemvector< Item > _items 中的项目列表.我需要根据显示顺序(类的数字成员)对其进行排序,我只是调用了一个带有谓词函数的简单排序。

sort(_items.begin(), _items.end(), sort_item_by_display_order);

谓词函数在哪里

bool sort_item_by_display_order (Item i, Item j)
{
    return i.GetDisplayOrder()>j.GetDisplayOrder();
}

GetDisplayOrder 是

int Item::GetDisplayOrder()
{
    return display_order;
}

但是...我在执行此操作时遇到了一些段错误。然后,我向谓词函数添加了一个计数器来检查它被调用了多少次,我发现当它崩溃时,计数器的大小大于 vector 的大小。

阅读一些内容后,我将代码更改为使用迭代器而不是使用 .begin() 和 .end()(这不应该一样吗?!)

所以我现在拥有的是

vector<Item>::iterator it_start, it_end;
it_start = _items.begin();
it_end = _items.end();
sort(it_start, it_end, sort_item_by_display_order);

具有相同的谓词功能。

现在它没有崩溃,但是......对于我做的大部分排序,我得到的迭代次数超过了我正在排序的 vector 的大小(这可能是正常的)

所以...用_items.begin()调用排序有什么区别?或 _it_start .据我所知,它们是相同的,对吧?!

还有一点。 Item是声明为的简单基类

class Item
{
  private:
  (...)
  public:
  (...)
}

作为引用,我使用了 http://www.cplusplus.com/reference/algorithm/sort/http://www.codeguru.com/forum/showthread.php?t=366064 .

在第二个链接中,他们向谓词函数参数添加了一个 const 和 &,这将使我的函数类似于这样

bool sort_item_by_display_order (const Item& i, const Item& j)
{
    return i.GetDisplayOrder()>j.GetDisplayOrder();
}

但是我得到一个编译器错误:

Item.cpp|1485|error: passing `const Item' as `this' argument of `int Item::GetDisplayOrder()' discards qualifiers|

啊……问题是……我做错了什么?

最佳答案

首先,比较函数的调用次数超过集合中元素的调用次数是完全正常的。例如,当我们说排序算法的复杂度 为 O(n log n) 时,这就是部分含义。对大小为 n 的集合执行的比较次数约为 n × log(n)。 (事实上​​,n 几乎是调用它的最小 次数;否则,我们甚至无法判断集合是否已经在第一名。)

其次,当您将参数设为 const 引用时会出现错误,因为您已将 GetDisplayOrder 声明为非 const 方法。不允许在 const 对象上调用非 const 成员函数,因为编译器假定该方法将尝试修改该对象,即使在这种情况下它不会修改任何内容。在声明和定义的末尾添加const:

int GetDisplayOrder() const;

int Item::GetDisplayOrder() const {
  return display_order;
}

最后,还有段错误的问题。您在此处显示的代码不足以查明原因。您是正确的,更改将迭代器传递给 sort 的方式不应该有任何效果。我怀疑您的 Item 类需要复制构造函数和赋值运算符,但它们要么没有实现,要么没有正确实现。对 vector 进行排序显然涉及在集合中移动项目,这需要一个有效的赋值运算符。将这些项目传递给原始比较函数(按值而不是常量引用接受参数)需要一个有效的复制构造函数。如果您正在进行任何动态内存分配(例如使用 newmalloc),您需要确保在分配时对内存进行“深度复制”或复制一个对象,或者您想出一种方法让多个对象共享相同的分配。如果多个对象认为它们都拥有相同的内存块,那么其中一个可能会在其他对象完成之前释放该内存,这肯定会导致段错误(当您访问已释放的内存时)。

关于c++ - std::sort 过火了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7932845/

相关文章:

c++ - C++ 中的枚举 - 函数如何赋值

algorithm - 是否有任何散列函数允许您调整表的大小而无需重新散列(删除+重新插入)内容?

java - 如何仅对列表的特定部分进行排序?

c++ - 获取指向成员 std::string::size 的指针无法与 libc++ 链接,但适用于 libstdc++

c++ - 读取 .bmp 文件 C++,错误的值?

c++ - 将透明的 .PNG 图像传输到屏幕上

algorithm - 高效的并行握手(组合)

java - 使用智能算法缩短 switch case

php - 数组排序后更改索引

Excel VBA - 在多列上排序后取消选择范围