使用 std::sort 对指针向量进行排序,导致地址混乱

Sorting a vector of pointers using std::sort resulting in jumbled addresses?

本文关键字:排序 地址 混乱 sort std 指针 向量 使用      更新时间:2023-10-16

我正在编写一个函数来对类指针的向量进行排序。在排序之前,向量包含以下指针:

{0x784170, 0x7841a0, 0x784050, 0x783f10, 0x783f40, 0x7832a0, 0x7832d0, 0x7831a0, 0x7831d0, 0x783080, 0x7830b0, 0x782f40, 0x782f70, 0x7827c0, 0x7827f0}

排序后,它包含以下内容:

{0x3141954a38, 0x3141954a38, 0x784050, 0x783f10, 0x783f40, 0x7832a0, 0x7832d0, 0x7831a0, 0x7831d0, 0x783080, 0x7830b0, 0x782f40, 0x782f70, 0x7827c0, 0x80}

以下是我的代码:

bool DNodeComparator(DNode* x, DNode* y)
{
return x->getDFN() < y->getDFN();
}
void sortFunction(){
    vector<DNode*> operations = ApplicationGraph.getOperations();
    std::sort(myvector.begin(), myvector.end(), mycomparator);
}
class DGraph
{
    private:
        vector<DNode*> Nodes;
    public:
        vector<DNode*> getOperations(){return Nodes;}
};

代码在包含 DNode* 对象向量的依赖关系图上运行。我返回这个指针向量,并按其 DFN 字段对每个节点进行排序。DNode 类包含 Operation* 对象、一些布尔标志和一个用于计算依赖关系图的深度优先编号的 int 值。第一行中显示的地址是在std::sort调用之前进行 gdb print operations调用的结果。第二行中的地址是紧随std::sort之后的print operations呼叫。

我已经尝试了更多的调试步骤,但仍然无法协调此错误。返回 DNode* 的向量会创建此向量的所需副本,该副本存储在单独的地址中,因此修改此新向量(例如通过添加更多 DNodes(不会修改图类中的实际向量。这应该不会引起任何问题,因为向量仍然包含每个 DNode*。

这是一个基于您的比较器的工作示例。

#include <algorithm>
#include <iostream>
#include <vector>
struct Obj {
  int id;
  int getID() {
    return id; }
  Obj(int i) : id(i) {} };
bool mycomparator(Obj* a, Obj* b) {
  return a->getID() < b->getID(); }
int main(int, char* []) {
  std::vector<Obj*> myvector;
  for (int i = 0; i < 4; ++i) {
    myvector.push_back(new Obj(i)); }
  std::random_shuffle(myvector.begin(), myvector.end());
  for (std::vector<Obj*>::iterator i = myvector.begin();
       i < myvector.end(); ++i) {
    std::cout << (*i) << " " << (*i)->getID() << " "; }
  std::cout << std::endl;
  std::sort(myvector.begin(), myvector.end(), mycomparator);
  for (std::vector<Obj*>::iterator i = myvector.begin();
       i < myvector.end(); ++i) {
    std::cout << (*i) << " " << (*i)->getID() << " "; }
  std::cout << std::endl;
  return 0; }

输出

0x80010308 2 0x80010318 1 0x80010328 3 0x800102f8 0
0x800102f8 0 0x80010318 1 0x80010308 2 0x80010328 3

您的代码与此有何不同?