将地址插入集合中,集合的大小小于预期

ins*_*nce 29 c++ set

我的大小是1.不应该是4吗?我将整数的地址插入集合中.

void func(set<int*>& s1, set<int*>& s2, int a)
{
    s1.insert(&a);
    s2.insert(&a);
}

int main()
{
    set<int*> s1, s2;

    int a = 1, b = 2, c = 3, d = 4;
    func(s1, s2, a);
    func(s1, s2, b);
    func(s1, s2, c);
    func(s1, s2, d);

    cout<<"  s1.size = "<<s1.size()<<"  s2.size = "<<s2.size()<<endl;
}
Run Code Online (Sandbox Code Playgroud)

Hol*_*olt 44

&afunc是本地参数的地址a,原始变量(不是地址a,b,cd),其中:

  1. 可以在不同的通话之间采取各种价值func;
  2. 一旦到达a声明范围的末尾(func此处结束),将变为无效指针.

在你的情况下,因为除了func连续调用4次之外什么都不做,所以这个参数的地址不会改变,这就是你得到1的大小(你插入相同的指针4次)的原因.

此行为是实现定义的(感谢@ Rakete1111),因为集合需要比较无效指针.

但是,通过s1s2(例如**s1.begin())访问指向的元素是未定义的行为.

  • @Holt看起来它是[实现定义的行为](/sf/answers/2148585911/). (3认同)
  • @Rakete1111谢谢,我不知道.我已经更新了答案. (2认同)

son*_*yao 28

该参数a按值传递,这意味着您要插入的是从参数复制的本地参数的地址.a每次func调用时都会构建,它们的地址可能相同或不同; 没有任何保证.

值得注意的是,a当退出函数时,参数将被销毁,然后插入的指针将被悬空.

你应该让传递通过引用,那么自变量的地址(即变量a,b,c,dmain())将被插入.这些地址不同,不会在身体内部悬空main().

void func(set<int*>& s1, set<int*>& s2, int& a)
{
    s1.insert(&a);
    s2.insert(&a);
}
Run Code Online (Sandbox Code Playgroud)

生活