Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: std::erase и std::vector  (Прочитано 8546 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 26-03-2012 15:51 » 

что за гремучая особенность std::erase - при удалении элемента из вектора:

имеется класс
Код:
struct s_socket_info
{
SOCKET m_S;


s_socket_info(SOCKET m_S=0)
:m_S(m_S)
{
}

void operator=(const s_socket_info& r)
{
m_S=r.m_S;
}

~s_socket_info()
{
if(m_S)
{
int res=::closesocket(m_S);
}

}
};

к примеру, удаляем какой-то НЕ ПОСЛЕДНИЙ элемент
Код:
std::vector<s_socket_info> m_clients;
...
std::vector<s_socket_info>::iterator it=m_clients.find(...);
...
m_clients->erase(it);


1) сначала для старого (стираемого) экземпляра вызывается оператор присваивания (старый хендл затёрся живым, ага)
2) а только потом для старого же экземпляра вызывается деструктор (живой хендл закрылся)

 я в осадке, если честно Отлично

пришлось вручную сначала закрывать хендл, только потом удалять экземпляр из вектора. И отказаться от деструктора
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 26-03-2012 16:03 » 

Алексей1153++, у тебя экземпляр "сидит" в векторе. Т.е. элемент вектора является "контейнером" для содержимого структуры; само содержимое структуры хранится не понять где. А тебе надо, чтобы каждое отдельное содержимое структуры было бы независимым экземпляром. Чтобы это сделать, в векторе надо хранить указатели, а не сами экземпляры. В противном случае имеешь то, что имеешь.
« Последнее редактирование: 26-03-2012 18:11 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 26-03-2012 16:09 » 

Dimka, про "само содержимое структуры храниться не понять где" не согласен, оно хранится конкретно в векторе Улыбаюсь

но вот вызов деструктора оказывается неконтролируемый. Поэтому да, либо указатели на экземпляры, либо ручная подчистка, только потом удаление
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 26-03-2012 18:14 » 

Алексей1153++, можешь не соглашаться, только это ничего не меняет. Экземпляр структуры невозможно отцепить от вектора, чтобы его корректно уничтожить. Отцепить него нельзя именно потому, что память под экземпляр выделена в конкретной позиции вектора. Максимум, что возможно, так это записать поверх другой экземпляр. Что, собственно, вектор и делает.

Так что ты сам себе "злобный буратино".
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 26-03-2012 20:29 » 

Алексей1153++, а почему у тебя оператор присваивания допускает перетирание без освобождения захваченного ресурса? В связи с этим обстоятельством, присоединяюсь насчёт злобного буратино Улыбаюсь

Добавлено через 2 минуты и 24 секунды:
Кстати, в п.2 что-то странное: вообще, вектор должен переместить все элементы, расположенные после текущего, а затем уничтожить последний элемент.
« Последнее редактирование: 26-03-2012 20:31 от Вад » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 27-03-2012 04:14 » 

Вад, оператор присваивания пробовал таким образом определять, но там проблем ещё больше - вообще неконтролируемо может произойти вызов и затирание.  Я пришёл к выводу, что в контейнере можно хранить только классы/структуры , для которых оператор присваивания и деструктор - дефолтные. Либо действительно хранить там указатели

насчёт п2 - видимо, создаётся временный экземпляр, через который происходит копирование. Потом этот временный мочится , и для него радостно вызывается деструктор

похожая фигня при инициализации вектора - создаётся временный экземпляр (ага, радостно вызывается конструктор Отлично ) , потом размазывается по всему вектору. Затем вызывается деструктор
« Последнее редактирование: 27-03-2012 04:16 от Алексей1153++ » Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 27-03-2012 08:09 » 

Я пришёл к выводу, что в контейнере можно хранить только классы/структуры , для которых оператор присваивания и деструктор - дефолтные.
Ну, в общем, да. Частный случай таких классических граблей - это использование auto_ptr в контейнерах. Поскольку копирование может происходить, скажем, при извлечении элемента из контейнера, можно крепко напороться.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines