Что именно происходит, когда я делаю buffer1.push_back(buffer2.front()) в C++?

Помоги мне понять это. Здесь контекст.

  • Я пишу программу на C++.
  • У меня есть 2 буфера (deque). Давайте назовем их buffer1 и buffer2;
  • У меня есть 2 потока: один поток заполняет buffer1 случайными значениями. Другой копирует самое старое значение buffer1 в buffer2;
  • Я использую мьютексы.

Я хочу скопировать значение в 1-й позиции buffer1 в buffer2 и, чтобы выполнить это, я пишу следующую строку кода:

РЕЗЬБА 1

   double a = 20.1;
   buffer1.push_back(a);

РЕЗЬБА 2

buffer2.push_back(buffer1.front());

Мой вопрос:выполняя это, я копирую значение или передаю значение по ссылке? Я объясняю свой вопрос. У меня случайная проблема с памятью при запуске программы. Я хочу быть уверен, что источник проблемы здесь.

Всем спасибо.

3 ответа

Для начала давайте взглянем на функции, которые вы вызываете. std::deque::push_back Функция получает аргумент по ссылке, поэтому копирование туда не требуется. А также std::deque::front возвращает reference (или же const_reference) так что копировать тоже нет.

Теперь давайте посмотрим на базовый контейнер, который по умолчанию std::vector и это та же история с его push_backа также front функции как для std::deque,

Однако если вы посмотрите на std::vector::push_back ссылаясь, вы увидите, что для первой перегрузки данные должны быть CopyInsertable, потому что именно так инициализируется элемент внутри вектора путем копирования объекта, который вы "отталкиваете" (или перемещаете, если ваш компилятор и тип данных его поддерживают).

Таким образом, в конце концов, если у вас есть сложный класс, вы должны следовать правилам три, пять или ноль, и если это так, то вы должны быть в порядке и не иметь проблемы с памятью по этому поводу в любом случае. Если вы действительно следуете правилам три, пять или ноль, и у вас все еще есть проблемы, то проблема может быть в другом месте. Попробуйте использовать отладчик памяти, например, Valgrind или аналогичный. А если у вас есть многопоточное приложение, вам необходимо защитить ресурсы, которые могут быть изменены несколькими потоками одновременно (например, с помощью мьютексов или семафоров).

В соответствии с этим std:: deque:: front возвращает ссылку на первый элемент:

Deque:: фронт:

Возвращает ссылку на первый элемент в контейнере deque.

И в соответствии с этим deque::push_back копирует (или перемещает) содержимое данного элемента:

Deque::push_back:

Добавляет новый элемент в конец контейнера deque, после его текущего последнего элемента. Содержимое val копируется (или перемещается) в новый элемент.

Я бы сказал, что ваша проблема в другом месте. Поскольку у вас есть фрагменты в разных потоках, их порядок может быть не определен. Вы можете закончить с этой последовательностью:

double a = 20.1;
buffer1.push_back(a);
buffer2.push_back(buffer1.front());

в этом случае все идет хорошо, или с этой последовательностью:

buffer2.push_back(buffer1.front());
double a = 20.1;
buffer1.push_back(a);

в этом случае вы звоните buffer1.front() на пустом контейнере. Конструктор копирования вызывается для некоторых случайных данных и приводит к проблемам с памятью.

Другие вопросы по тегам