Повторяющийся вектор уникального указателя

#c #iterator #segmentation-fault #c 14 #unique-ptr

#c #итератор #ошибка сегментации #c 14 #уникальный-ptr

Вопрос:

Я прочитал все возможные ссылки на интеллектуальные указатели, семантику перемещения и итераторы, но я все еще пытаюсь понять, почему следующий C 14 сегментирует код:

 #include <iostream>
#include <vector>
#include <memory>

using namespace std;

int main(int argc, char **argv)
{
  vector<unique_ptr<int>> ints (10);

  for(int i = 0; i < 10;   i) {
    unique_ptr<int> number = make_unique<int>(5);
    ints.push_back(move(number));
  }

  for(autoamp; n : ints) {
    cout << *n << endl;
  }

  return 0;
}
  

Скомпилирован с:

 g   <filename> -std=c  14 -o <executable>
  

Ответ №1:

 vector<unique_ptr<int>> ints (10);
  

Это инициализирует vector 10 unique_ptr секунд со значениями по умолчанию. То есть нулевые указатели.

Затем вы пытаетесь разыменовать их в цикле.

Вы, вероятно, хотели сказать

 vector<unique_ptr<int>> ints;
ints.reserve(10); // changes capacity, but not size
  

Комментарии:

1. Или vector<unique_ptr<int>> ints(10,5) без цикла

2. Это не сработает, @Trevir. 5 будет использоваться для инициализации unique_ptr<int> , что бессмысленно.

3. @Trevir но вы не можете скопировать значение a unique_ptr , которое требуется для значения по умолчанию, если вы его укажете.

Ответ №2:

 vector<unique_ptr<int>> ints (10);

// ...

ints.push_back(move(number));
  

Вы выделяете вектор с 10 элементами, созданными по умолчанию, затем добавляете элементы с push_back помощью: первые 10 элементов инициализируются нулевыми указателями, таким образом, segfault .

Попробуйте:

 vector<unique_ptr<int>> ints (10);

for(autoamp; ptr : ints) {
    ptr = make_unique<int>(5);
}