Согласно говорить Герб Саттер в CppCon 2015, shared_ptr
должен быть признан недействительным после модификацииЗачем нужно менять общий указатель после изменения?
auto sv = make_shared<vector<int>>(100);
shared_ptr<vector<int>>* sv2 = &sv;
vector<int>* vec = &*sv;
int* ptr = &(*sv)[0];
*ptr = 1 ;
vec->push_back(2); //A: modification
*ptr = 5; //Error: ptr was invalidated by "push_back" on line A
ptr = &(*sv)[0];
(*sv2).reset(); //B: modification
vec->push_back(6); //Error: vec was invalidated by "reset" on line B
Моего компилятора не ловит ни один из этих ошибок. Во всяком случае, мы используем интеллектуальные указатели для предотвращения утечки памяти. В чем причина подавления модификации shared_ptr
? Во избежание сюрпризов? Если это так, не можем ли мы объявить его как const
? С другой стороны, если многие операции с vector
не могут быть применены из-за share_ptr
, неужели это неудобно?
После прочтения комментариев, теперь я начинаю понимать, что он здесь делает. Модификация shared_ptr
делает недействительными другие необработанные указатели, указывающие на нее.
Как указано в комментарии, push_back
может перераспределить, что может привести к аннулированию ptr
. Если он не перераспределяется, должно ли оставаться ptr
? Если он перераспределит, не будет ли это проще и конструктивнее, если компилятор просто переведет всех своих приятелей на новую территорию, скажем, назначит эти исходные указатели новым адресом?
Чтобы быть понятным, общий указатель не является недействительным; он говорит, что другие, не управляемые указатели на один и тот же ресурс недействительны. Я тоже не могу ответить. –
Можете ли вы указать, где в видео он говорит это? – AndyG
'vec-> push_back' может перераспределять, и в этом случае указатели на старое распределение становятся недействительными. Это относится к 'ptr' в примере A. Аналогичным образом, если вы сбросите' shared_ptr' и это единственный владелец вектора, тогда этот вектор будет уничтожен и указатели на (и в) этот вектор станут недействительными.Это пример 'vec' в примере B. – dyp