Форум программистов, компьютерный форум CyberForum.ru

Move Semantic - будет ли утечка? - C++

Восстановить пароль Регистрация
 
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
27.03.2014, 23:27     Move Semantic - будет ли утечка? #1
Есть класс
C++
1
2
3
4
5
6
7
8
9
10
class ChannelsScaleDraw
{
public:
    void updateLabelsBuffer(const std::vector<QString> &labels)
          {
                 l = std::move(labels);
          }
private:
    std::vector<QString> l;
};
Что-то не могу сообразить: куда подевается содержимое вектора l ? По идее будет утечка памяти ведь? Правильным подходом будет использование std::vector<>::assign() ?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.03.2014, 23:27     Move Semantic - будет ли утечка?
Посмотрите здесь:

C++ Будет ли утечка памяти при выполнении данного кода?
C++ Move semantics implementation..
Изменить метод move C++
move семантика C++
std::move() C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
27.03.2014, 23:48     Move Semantic - будет ли утечка? #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
gromo, все будет хорошо. Конкретно в твоем случае вообще не будет перемещения. Будет обычное присваивание. Потому что vector не определяет такого оператора:
C++
1
vector& operator=(vector const && x);
Добавлено через 7 минут
А вот про семантику
C++
1
vector& operator=(vector && other);
Move assignment operator. Replaces the contents with those of other using move semantics (i.e. the data in other is moved from other into this container). other is in a valid but unspecified state afterwards. If std::allocator_traits<allocator_type>:: propagate_on_container_move_assignment() is true, the target allocator is replaced by a copy of the source allocator. If it is false and the source and the taget allocators do not compare equal, the target cannot take ownership of the source memory and must move-assign each element individually, allocating additional memory using its own allocator as needed.
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
28.03.2014, 00:19  [ТС]     Move Semantic - будет ли утечка? #3
Цитата Сообщение от DrOffset Посмотреть сообщение
Потому что vector не определяет такого оператора:
Да уж, забыл но а если без const и без & ? Вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class ChannelsScaleDraw
{
public:
    void updateLabelsBuffer(std::vector<QString> labels)
          {
                 l = std::move(labels);
          }
private:
    std::vector<QString> l;
};
void someFunc()
{
    std::vector<QString> vec;
    // заполнили vec
    ChannelsScaleDraw obj;
    obj.updateLabelsBuffer(std::move(vec));
}
Добавлено через 7 минут
vec создается на стеке функции someFunc(), может нет смысла его перемещать из нее? просто передать его по обычной lvalue reference в updateLabelsBuffer() и уже там перемещать как первом посте?

Только думал, что разобрался с move семантикой и опять каша в голове

Добавлено через 11 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
А вот про семантику
Спасибо, когда-нибудь почитаю подробнее про это, но сейчас мой мозг пока не готов к <type_traits>-подобному материалу Может через полгодика
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
28.03.2014, 00:24     Move Semantic - будет ли утечка? #4
Цитата Сообщение от gromo Посмотреть сообщение
а если без const и без & ? Вот так:
Будет выполнено перемещение для каждого элемента, если аллокатор не может быть перемещен, или если у нас rvalue. В противном случае, реализация в моем компиляторе делает следующее:
Перемещает содержимое текущего вектора во временный локальный объект. Потом делает swap с содержимым аргумента оператора. Таким образом обеспечивается перемещение и корректное освобождение памяти для существующих объектов. Т.е. в любом случае будет все нормально. Если нужно, могу завтра поискать формальное подтверждение описанному поведению.
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
28.03.2014, 00:37  [ТС]     Move Semantic - будет ли утечка? #5
Цитата Сообщение от DrOffset Посмотреть сообщение
Если нужно, могу завтра поискать формальное подтверждение описанному поведению.
Конечно нужно! Буду очень благодарен вам.
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
28.03.2014, 11:34     Move Semantic - будет ли утечка? #6
gromo, не пойму в чем трудность?:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
 
class A
{
   std::vector<std::string> l;
public:
   void foo(std::vector<std::string>&& v) {
      l = std::move(v);
   }
   template <typename T>
   void foo2(T&& v) {
      l = std::move(v);
   }
 
   void print() const {
      std::cout << "A.l.size() = " << l.size() << "\n";
      for (const auto& str : l) std::cout << str << " ";
      std::cout << "\n";
   }
};
int main()
{
   std::vector<std::string> vec {"Hello", "world"};
   A a;
   a.foo(std::move(vec));
   a.print();
   std::cout << "vec.size() = " << vec.size() << "\n";
 
   std::vector<std::string> vec2 {"Hello_2", "world_2"};
   a.foo2(vec2);
   a.print();
   std::cout << "vec2.size() = " << vec2.size() << "\n";
 
   return 0;
}
Или тут что то другое надо?
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
28.03.2014, 12:00  [ТС]     Move Semantic - будет ли утечка? #7
Цитата Сообщение от DiffEreD Посмотреть сообщение
Или тут что то другое надо?
Надо только избежать ненужного копирования

В таком случае можно предоставить одну функцию с universal reference в качестве параметра, например, в моем случае так:
C++
1
2
3
4
5
6
7
8
9
10
class ChannelsScaleDraw
   {
   public:
       template <typename T> updateLabelsBuffer(T&& labels)
             {
                    l = std::move(labels);
             }
   private:
       std::vector<QString> l;
   };
И теперь если мы передадим rvalue либо lvalue в updateLabelsBuf(), то в любом случае лишнего копирования не будет?

Добавлено через 3 минуты
а насчет этого
Цитата Сообщение от DrOffset Посмотреть сообщение
Move assignment operator. Replaces the contents with those of other using move semantics (i.e. the data in other is moved from other into this container). other is in a valid but unspecified state afterwards. If std::allocator_traits<allocator_type>:: propagate_on_container_move_assignment() is true, the target allocator is replaced by a copy of the source allocator. If it is false and the source and the taget allocators do not compare equal, the target cannot take ownership of the source memory and must move-assign each element individually, allocating additional memory using its own allocator as needed.
Я так понял если аллокаторы двух контейнеров будут совместимыми, что определяется на этапе компиляции, то аллокаторы перемещаемого и получающего контейнеров обменяются? Написано, что аллокатор будет 'replaced' но как тогда уничтожится тот контейнер, в который перемещают (l в данном случае) другой контейнер (labels в данном случае)?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.03.2014, 19:29     Move Semantic - будет ли утечка?
Еще ссылки по теме:

[C++11] move\rvalue ref semantic C++
Move semantics в C++11 C++
Std::move C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
28.03.2014, 19:29     Move Semantic - будет ли утечка? #8
Цитата Сообщение от gromo Посмотреть сообщение
Написано, что аллокатор будет 'replaced' но как тогда уничтожится тот контейнер, в который перемещают (l в данном случае) другой контейнер (labels в данном случае)?
Один из вариантов я привел: перед заменой аллокатора, текущий вектор перемещают во временный локальный объект, деструктор которого вызовется в конце метода.
Вот требования стандарта (23.2.1):
Requires: If allocator_traits<allocator_type>:: propagate_on_container_move_assignment::value is
false, T is MoveInsertable into X and MoveAssignable. All existing elements of a are either move assigned to or destroyed.
Т.е в целом неважно как будет реализовано, но данное требование должно выполняться.
Yandex
Объявления
28.03.2014, 19:29     Move Semantic - будет ли утечка?
Ответ Создать тему
Опции темы

Текущее время: 20:13. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru