Каковы все способы увеличения use_count в std :: shared_ptr?

У меня два shared_ptrуказывает на то же intто есть звонит get() на них возвращает один и тот же адрес. Но зовет use_count() на них возвращается 1, Когда последний из них выходит из области видимости, он пытается освободить память, уже освобожденную другим, вызывая двойную ошибку времени выполнения:

#include <memory>
#include <iostream>
using namespace std;

int main() {
shared_ptr<int> sp1(make_shared<int>(7));
shared_ptr<int> sp2(&(*sp1));
cout << sp1.use_count() << endl;  // 1
cout << sp2.use_count() << endl;  // 1
cout << sp1.get() << endl;        // same address
cout << sp2.get() << endl;        // same address
}
// ^ Double free runtime error at closing brace.

То же самое происходит в этом варианте с явно объявленным необработанным указателем:

int main() {
int *raw_ptr = new int(8);
shared_ptr<int> sp3(raw_ptr);
shared_ptr<int> sp4(raw_ptr);
cout << sp3.use_count() << endl;  // 1
cout << sp4.use_count() << endl;  // 1
cout << sp3.get() << endl;        // same address
cout << sp4.get() << endl;        // same address
}
// ^ Double free runtime error at closing brace.

Почему use_count() вернуть 1 (но нет 2) если оба shared_ptrуказывает на то же самое? Если use_count() возвращенный 1Тогда почему была попытка освободить int дважды? Я думал, что shared_ptr вырастет use_count один, если и только если он указывает на тот же адрес, что и его братья shared_ptrs.

Это std::shared_ptr«s use_count увеличивается только на первое shared_ptrконструирование по необработанному указателю (или присвоение необработанному указателю, если построено по умолчанию), а затем по дополнительному shared_ptrs ‘copy-construction или уступка любым из предыдущих shared_ptrs? И каковы все другие способы приращения, если таковые имеются?

2

Решение

Когда вы даете указатель на shared_ptrэтот общий указатель становится владельцем этого указателя. Вам больше не разрешено delete это, передать его другому shared_ptr, или похожие. Там нет глобальной таблицы поиска для нового shared_ptr проверить, чтобы найти, что уже есть другой shared_ptr который уже имеет указатель или что-то в этом роде.

Иными словами, ошибка двойного освобождения произошла, когда второй shared_ptr был создан путем передачи в тот же указатель, а не копирование shared_ptr сам (который увеличивает счетчик использования). Тот факт, что вы не можете наблюдать неопределенное поведение до тех пор, пока позже не изменится, где это происходит на самом деле.

6

Другие решения

Вы должны использовать конструктор копирования shared_ptr для правильного построения второго общего указателя.

1

По вопросам рекламы [email protected]