Вставляя адреса в наборы, размер наборов меньше ожидаемых
Я получаю размер 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;
}
Ответы
Ответ 1
&a
внутри func
- адрес локального параметра a
, а не адрес исходной переменной (a
, b
, c
или d
), который:
- Может принимать различные значения между различными вызовами
func
;
- Становится недействительным указателем, когда вы достигнете конца области, в которой объявлен
a
(конец func
здесь).
В вашем случае, поскольку вы ничего не делаете, но вызываете func
4 раза подряд, адрес этого параметра не меняется, поэтому вы получаете размер 1 (вы вставляете один и тот же указатель 4 раза).
Это поведение определено в реализации (спасибо @Rakete1111), поскольку наборы должны будут сравнивать недопустимые указатели.
Доступ к заостренному элементу через s1
или s2
(например, **s1.begin()
) есть поведение undefined.
Ответ 2
Параметр a
передается по значению, это означает, что вы вставляете адрес локального параметра, скопированного из аргументов. a
будет создаваться каждый раз, когда вызывается func
, их адреса могут быть одинаковыми или разными; ничего не гарантировано.
И стоит отметить, что параметр a
будет уничтожен при выходе из функции, после чего вставляемые указатели будут свисать.
Вы должны сделать это по-ссылке, тогда будут вставлены адреса аргументов (т.е. будут вставлены переменные a
, b
, c
, d
в main()
). Эти адреса различны и не будут свисать внутри тела main()
.
void func(set<int*>& s1, set<int*>& s2, int& a)
{
s1.insert(&a);
s2.insert(&a);
}
LIVE