Вариант примера Дарио таков:
void Foo(shared_ptr<Bar> a, shared_ptr<Bar> b){ ... }
int main() {
Foo(shared_ptr<Bar>(new Bar), shared_ptr<Bar>(new Bar));
}
, что может привести к утечке памяти. Между оценкой двух параметров отсутствует точка последовательности, поэтому не только второй аргумент может быть оценен перед первым, но и оба объекта Bar могут быть созданы до любого из shared_ptr
'
То есть вместо того, чтобы оцениваться как
Bar* b0 = new Bar();
arg0 = shared_ptr<Bar>(b0);
Bar* b1 = new Bar();
arg1 = shared_ptr<Bar>(b1);
Foo(arg0, arg1);
(что было бы безопасно, потому что, если b0
будет успешно выделено, оно будет немедленно обернуто в shared_ptr
), это можно оценить как:
Bar* b0 = new Bar();
Bar* b1 = new Bar();
arg0 = shared_ptr<Bar>(b0);
arg1 = shared_ptr<Bar>(b1);
Foo(arg0, arg1);
, что означает, что если b0
будет успешно выделен, а b1
выдает исключение, то b0
никогда не будет удален.