【问题标题】:Why does std::sort throw a segmentation fault on this code?为什么 std::sort 会在此代码上引发分段错误?
【发布时间】:2011-08-08 05:50:58
【问题描述】:

有人可以解释为什么下面的排序会导致段错误吗?这是 g++(指针排序向量)的已知错误吗?我正在使用 g++ 4.5.2 进行编译。

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

typedef vector<int> A;
bool face_cmp(const A *x, const A *y) {
  return x != y;
}

int main(int argc, char* argv[]) {

  vector<A *> vec;
  for (int i=0; i<100; i++) {
    vec.push_back( new vector<int>(i%100, i*i) );
  }

  vector<A *>::iterator it;
  sort(vec.begin(), vec.end(), face_cmp);

  return EXIT_SUCCESS;
}

在键盘上编译给出:

/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/debug/safe_iterator.h:240:
    error: attempt to decrement a dereferenceable (start-of-sequence)     
    iterator.

Objects involved in the operation:
iterator "this" @ 0x0xbf4b0844 {
type = N11__gnu_debug14_Safe_iteratorIN9__gnu_cxx17__normal_iteratorIPPN15__gnu_debug_def6vectorIiSaIiEEEN10__gnu_norm6vectorIS7_SaIS7_EEEEENS4_IS7_SB_EEEE (mutable iterator);
  state = dereferenceable (start-of-sequence);
  references sequence with type `N15__gnu_debug_def6vectorIPNS0_IiSaIiEEESaIS3_EEE' @ 0x0xbf4b0844
}

感谢您的所有快速回复。原来的 comp 函数是:

if (x == y) return false;
if (x->size() < y->size()) return true;
else if (x->size() > y->size()) return false;
else {
  for (register int i=0; i<x->size(); i++) {
    if ((*x)[i] < (*y)[i]) return true;
  }
  return false;
}

我只是更改了第一行并删除了其余部分。但事实证明,它也不是严格的弱排序(我忘记了如果 (*x)[i] > (*y)[i] 的情况)。我可能应该一开始就发布整个功能。不过,再次感谢!

【问题讨论】:

  • 你的比较函数是假的。它不是比较值,而只是比较指针 - 充其量。
  • 简化以使代码更短。它仍然会产生段错误。
  • 你是在比较vector的指针,必须在数据上比较
  • 那么,实际的比较函数是什么?因为将其更改为合理的东西可以修复段错误。 ideone.com/qaaOA
  • 指针向量排序没有问题;问题在于在比较函数中使用不等于而不是小于。

标签: c++ sorting segmentation-fault


【解决方案1】:

比较函数必须定义严格的弱排序,这意味着a &lt; bb &lt; a 不能同时为真。您的比较函数没有此属性。

它没有定义任何“前后”关系,因此依赖这个属性的算法不能正常运行也就不足为奇了。

【讨论】:

    【解决方案2】:

    std::sort 的第三个参数应该是一个函数(或函数对象),如果compare(a, b)true,那么compare(b, a) 应该是false,但你的不是这样。所以你的程序是UB,可以给出任何结果。

    【讨论】:

    • 全部正确。但仍然没有真正回答这个问题。你需要它解释实际需要由比较运算符定义的关系。
    【解决方案3】:

    不,您的代码是错误的。 std::sort 的比较函数必须使用

    bool face_cmp(const A *x, const A *y) {
      return *x < *y;
    }
    

    【讨论】:

    • 其他两个答案说明得更好,严格的弱排序是我真正想说的:)
    • 当然你可以用 cplusplus.com/reference/stl/vector/operators 。请删除您的反对票。我的回答不如其他人好,但也不是错的。
    • @ArunMu 是的,你可以像这样比较向量。
    • 比较运算符确实不需要需要使用''或许多其他比较。这是一个弱答案,因为您没有定义比较运算符必须定义的关系。
    • @Martin:是的,这就是我在第一条评论中提到的观点。但是我的答案确实包含一些代码,因此它可能对 OP 有用。
    【解决方案4】:

    确保您只使用大于或小于。 DO NO USE 等于。等于将 SEGFAULT 与某些数据集:

    // Good
    bool face_cmp(const A *x, const A *y) {
      return *x < *y;
    }
    
    // Also okay for reverse sorting
    bool face_cmp(const A *x, const A *y) {
      return *x > *y;
    }
    
    // This will SEGFAULT
    bool face_cmp(const A *x, const A *y) {
      return *x <= *y;
    }
    

    【讨论】:

      【解决方案5】:

      将比较函数定义为

      bool face_cmp(const A *x, const A *y) {
        return x < y;
      }
      

      【讨论】:

      • 你应该向 OP 询问。
      • OP比较值显示的原始比较函数(它只是优化了相同的对象比较...)
      猜你喜欢
      • 2023-02-03
      • 2020-03-25
      • 1970-01-01
      • 1970-01-01
      • 2013-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-30
      相关资源
      最近更新 更多