【问题标题】:Priority queue changes its content优先队列更改其内容
【发布时间】:2016-06-23 12:00:51
【问题描述】:

我一直在尝试创建一个 优先级队列,其中每个元素都是一个 pair,其中存储了一个 指向 unsigned int 的指针和一个无符号整数。问题是,每当我将一对添加到优先级队列中时,之前添加的对指向的元素会将其值切换为 0。

这里是代码

#include <iostream>
#include <vector>
#include <utility>
#include <queue>

typedef unsigned int ui;
typedef std::pair<ui*, ui> Ppuiui;
typedef std::priority_queue<Ppuiui> Queue;

void showPQ(Queue Q)
{
    while(!Q.empty())
    {
        std::cout << *(Q.top().first) << " -> " << Q.top().second << std::endl;
        Q.pop();
    }
    std::cout << std::endl;
}

int main(void)
{
    std::vector<ui> distance;
    Queue Q;

    //Adding elements to the priority queue while showing them
    distance.push_back(2500);
    Q.push(Ppuiui(&(distance[0]), 0));
    showPQ(Q);

    distance.push_back(1000);
    Q.push(Ppuiui(&(distance[1]), 1));
    showPQ(Q);

    distance.push_back(500);
    Q.push(Ppuiui(&(distance[2]), 2));
    showPQ(Q);

    //Checking that none of the values has changed in 'distance'
    std::cout << distance[0] << std::endl;
    std::cout << distance[1] << std::endl;
    std::cout << distance[2] << std::endl;
}

及其执行结果

2500 -> 0

1000 -> 1
0 -> 0

0 -> 1
500 -> 2
0 -> 0

2500
1000
500

为什么会这样?

注意:我很清楚这段代码中的优先级队列比较的是内存地址,而不是它们所包含的值。

【问题讨论】:

    标签: c++ pointers priority-queue std-pair


    【解决方案1】:

    您违反了迭代器验证规则。您获取一个指向向量元素的指针,然后在这样做之后将另一个元素添加到向量中。如果重新分配,添加元素将导致所有迭代器、指针和引用无效。

    由于您从未为向量保留大小,至少前两个push_backs 将导致重新分配,这意味着您有一个悬空指针。如果您确实需要在向量中存储指向元素的指针,那么您将不得不在向量中保留空间,这样就不会发生重新分配。

    有关容器操作何时以及受什么影响的更多信息,请参阅:Iterator invalidation rules

    【讨论】:

      【解决方案2】:

      你在操作中添加的指针,如

      distance.push_back(2500);
      Q.push(Ppuiui(&(distance[0]), 0));
      

      当您向向量中保留的向量添加更多内容时,它们会悬空。这是因为向量会将旧值复制到一个更新、更大的数组中。

      如果你想使用这样的地址,你应该使用distance.reserve,以确保事先有足够的空间。

      【讨论】:

        猜你喜欢
        • 2014-05-20
        • 1970-01-01
        • 2012-02-24
        • 1970-01-01
        • 2012-03-03
        • 1970-01-01
        • 2021-02-26
        • 2019-09-18
        • 2012-06-15
        相关资源
        最近更新 更多