C++ 通过间接寻址使指针集无效

C++ 通过间接寻址使指针集无效,c++,set,undefined-behavior,C++,Set,Undefined Behavior,考虑以下程序。它创建一组指向int的指针,并使用一个自定义的indrect_less比较器,该比较器根据指向整数的值对集合进行排序。完成后,我将更改其中一个指向整数的值。然后,可以看到集合的顺序不再被排序(我想是因为集合不知道发生了什么变化) (不要介意C++0x循环,我在VS2010上运行) #包括 #包括 使用名称空间std; 结构间接无{ 布尔运算符()(int*l,int*r)常量 { 返回*l

考虑以下程序。它创建一组指向int的指针,并使用一个自定义的indrect_less比较器,该比较器根据指向整数的值对集合进行排序。完成后,我将更改其中一个指向整数的值。然后,可以看到集合的顺序不再被排序(我想是因为集合不知道发生了什么变化)

(不要介意C++0x循环,我在VS2010上运行)

#包括
#包括
使用名称空间std;
结构间接无{
布尔运算符()(int*l,int*r)常量
{
返回*l<*r;
}
};
int main()
{
设置myset;
int*a=新的int(5);
int*b=新的int(6);
int*c=新的int(7);
myset.插入(a);
myset.插入(b);
myset.插入(c);

是的,
std::set
假设元素是不可变的。如果危险的话,在每次更改后自己重新排序是很危险的。不过,我不建议使用另一种集合类型。

是的,
std::set
假设元素是不可变的。如果危险的话,在每次更改后自己重新排序是很危险的。但是,我不建议这样做ugh:使用其他集合类型。

1)是的,集合不允许修改其元素

2) 除了删除旧值并插入新值外,还可以用新构造的值替换旧集

3) 否是,集合不允许修改其元素

2) 除了删除旧值并插入新值外,还可以用新构造的值替换旧集

3) 不

1)我不知道行为是未定义的。本例中的另一个转折点是集合的元素没有改变——集合的每个元素都是一个指针。您是在执行行“*a=9”前后打印集合的(指针)元素吗“,我相信您会发现指针值在赋值前后的顺序是相同的。更改的是一个集合元素指向的值。这是在集合的主持之外发生的,因此集合无法维持您希望的顺序

2) 限定的“是”。这将强制使用间接的_less()对集合的元素进行排序。再次,请注意,您是根据每个取消引用的指针的值对集合的元素(指针)进行排序。然而,这让我觉得有点冒险,原因正是您所描述的

从打印输出中的图例“Set contains:”中,我假定此示例努力形成一组整数。但是,定义的集合(即“Set”)实际上由指向整数的指针组成,而不是整数本身。我相信,所需集合和实际集合之间的这种不一致是问题的根本原因

3) 参见2)。

1)我不知道行为是未定义的。本例中的另一个转折点是集合的元素没有改变——集合的每个元素都是指针。您是在执行行“*a=9”前后打印集合的(指针)元素吗“,我相信您会发现指针值在赋值前后的顺序是相同的。更改的是一个集合元素指向的值。这是在集合的主持之外发生的,因此集合无法维持您希望的顺序

2) 限定的“是”。这将强制使用间接的_less()对集合的元素进行排序。再次,请注意,您是根据每个取消引用的指针的值对集合的元素(指针)进行排序。然而,这让我觉得有点冒险,原因正是您所描述的

从打印输出中的图例“Set contains:”中,我假定此示例努力形成一组整数。但是,定义的集合(即“Set”)实际上由指向整数的指针组成,而不是整数本身。我相信,所需集合和实际集合之间的这种不一致是问题的根本原因


3) 请参见2)。

在该行之后是否定义了任何行为?您能否可靠地迭代集合(使用未定义的顺序)例如?Undefined不是这样工作的。一旦调用Undefined behavior,所有赌注都将被取消。您的程序可能会执行任何操作,包括看起来继续工作。直到它不工作。通常是在为重要人员演示代码时。在该行之后是否定义了任何行为?您能否可靠地迭代该集合(使用未定义的顺序)例如?未定义不会以这种方式工作。一旦调用未定义的行为,所有赌注都将取消。您的程序可能会执行任何操作,包括看起来继续工作。直到它不工作。通常在为重要人员演示代码时。
#include <iostream>
#include <set>
using namespace std;

struct indirect_less {
    bool operator()(int* l, int* r) const
    {
        return *l < *r;
    }
};

int main()
{
    set<int*, indirect_less> myset;

    int* a = new int(5);
    int* b = new int(6);
    int* c = new int(7);

    myset.insert(a);
    myset.insert(b);
    myset.insert(c);

    cout << "Set contains: ";
    // (outputs: 5 6 7)

    for (auto i = myset.begin(), end = myset.end(); i != end; ++i)
    {
        cout << **i << " ";
    }

    cout << endl << "Modifying *a" << endl;
    *a = 9;         // point of interest
    cout << "Set contains: ";
    // (outputs: 9 6 7 - unsorted order)

    for (auto i = myset.begin(), end = myset.end(); i != end; ++i)
    {
        cout << **i << " ";
    }

    cout << endl;

    cin.get();

    return 0;
}