【问题标题】:Unexpected (for me at least) behaviour when sorting a vector of custom elements对自定义元素向量进行排序时出现意外(至少对我而言)行为
【发布时间】:2019-12-01 09:18:03
【问题描述】:

我最近在实施某些事情时遇到了这个问题。我有一个自定义的树状结构,其中包含一个值和一个子向量。插入子节点时,我希望它们以随机顺序出现,并且我需要跟踪插入的最后一个元素以供将来的某些操作使用。事实证明,如果我保存一个指向最后一个节点的向量的指针,在对向量进行排序后,指针仍然有效,但它现在指向一个完全不同的向量。这是一个最小的例子:

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

struct Node {
    int value;
    std::vector<Node> nxt;

    bool operator<(const Node& other) {
        return value < other.value;
    }
    /* Having this custom swap function doesn't make a difference
    *friend void swap(Node& lhs, Node& rhs) {
    *    std::swap(lhs.value, rhs.value);
    *    lhs.nxt.swap(rhs.nxt);
    *}
    */
};


int main() {
    Node node1;
    node1.value = 1;
    Node node2;
    node2.value = 2;
    Node node3;
    node3.value = 3;
    Node node4;
    node4.value = 4;

    std::vector<Node> container;
    container.push_back(node2);
    container.push_back(node1);
    container.push_back(node4);
    container.push_back(node3);
    std::vector<Node>* node3_vec = &container.back().nxt;
    node3_vec->push_back(node1);
    std::cout << "Address of the vector: " << node3_vec << std::endl;
    std::cout << "Size of the vector: " << node3_vec->size() << std::endl;

    std::sort(container.begin(), container.end());

    std::cout << "Address of the vector post sort: " << node3_vec << std::endl;
    std::cout << "Size of the vector post sort: " << node3_vec->size() << std::endl;

    //Inside the container
    std::cout << "Value of the node inside the container: " << container[2].value << std::endl;
    std::cout << "Address of the vector: " << &container[2].nxt << std::endl;
    std::cout << "Size of the vector: " << container[2].nxt.size() << std::endl;
    return 0;
}

我尝试使用一些自定义的std::swap 实现,但我似乎无法改变这种行为。我怎样才能使它在排序后,指向向量的指针指向同一个向量?目前,我在排序后执行额外的搜索以找到所需的元素。

也有人可以向我指出一些解释这种行为的文档吗?

【问题讨论】:

标签: c++ sorting swap stdvector


【解决方案1】:

sort 之后,原始指针node3_vec 仍将指向container 中的最后一个Node。在sort 之后,这将是node4 的副本,而node3 的副本曾经位于排序之前。

【讨论】:

    【解决方案2】:

    每次保存指针时,都会将地址保存在内存中下一个向量所在的位置。 如果您对容器进行排序,元素将四处移动,并且不同的元素将最终到达该地址。

    就像你记得你的朋友住在街上的 4 号房子一样。然后你要求街上的每个人都搬家,以便他们有秩序。

    很可能会有其他人住在 4 号房子,但不是你的朋友!

    我不确定是否有任何文档,因为这是预期的!

    【讨论】:

    • 我希望出于效率原因,您不会真正交换节点,而只是交换向量指向的内存。
    猜你喜欢
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多