Russian Qt Forum
Март 29, 2024, 11:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Игра Танки. Segmentation error  (Прочитано 11243 раз)
8Observer8
Гость
« Ответ #15 : Январь 13, 2015, 12:24 »

Цитировать
Здесь всё нормально теперь. Там проблема была - ошибка в пути. Теперь этот момент проходит. Я выше написал
Эх.. Ничего вы не поняли(
Не понял
Записан
8Observer8
Гость
« Ответ #16 : Январь 13, 2015, 13:52 »

Не, ну вы же пишите статьи по "современным контейнерам", а тут недоумеваете:

Код
C++ (Qt)
   std::vector<QOpenGLTexture*> m_textures;
   ...
   frame = image.copy( 257, 112, 15, 15 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
   frame = image.copy( 272, 112, 16, 16 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
   frame = image.copy( 287, 111, 18, 18 );
   m_textures.push_back( new QOpenGLTexture( frame ) );
 
Подскажите, пожалуйста, что тут не так?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #17 : Январь 13, 2015, 14:02 »

На Вындоуз не пошло (нужен 5.4), а на Mac у меня вылет в др месте. Была такая конструкция  
Код
C++ (Qt)
   for ( auto iterOfProjectile = m_projectiles.begin(); iterOfProjectile != m_projectiles.end(); ++iterOfProjectile )
   {
                   ....
                   m_projectiles.erase( iterOfProjectile );
                   addProjectileExplosion( x0, y0 );
 
Если erase, то итератор становится невалидным, напр ++ с ним уже нельзя. Как с auto - не читал, но наверное тоже, т.к. здесь вылетала. Я сделал по-старинке (измененный файл в аттаче), вылета нет

Код
C++ (Qt)
typedef std::map<int, Projectile*> TMap;
TMap::iterator iterOfProjectile = m_projectiles.begin();
 
//    for ( auto iterOfProjectile = m_projectiles.begin(); iterOfProjectile != m_projectiles.end(); ++iterOfProjectile )
   while (iterOfProjectile != m_projectiles.end())
   {
       Projectile *projectile = iterOfProjectile->second;
 
       float x0 = projectile->x0();
       float y0 = projectile->y0();
 
bool doDel = false;
 
       switch ( projectile->direction() ) {
           case Projectile::Up:
               projectile->setY0( projectile->y0() - step );
               doDel = projectile->y0() <= 0.0f;
               break;
           case Projectile::Left:
               projectile->setX0( projectile->x0() - step );
               doDel = projectile->x0() < 0.0f;
               break;
           case Projectile::Down:
               projectile->setY0( projectile->y0() + step );
               doDel = projectile->y0() >= ( m_canvasHeight - projectile->height() );
               break;
           case Projectile::Right:
               projectile->setX0( projectile->x0() + step );
               doDel = projectile->x0() > ( m_canvasWidth - projectile->width() );
               break;
       }
 
if (doDel )
{
delete projectile;
m_projectiles.erase( iterOfProjectile++ );
addProjectileExplosion( x0, y0 );
}
else
iterOfProjectile++;
   }
 
Кстати как то же с auto?
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #18 : Январь 13, 2015, 14:26 »

Цитировать
Подскажите, пожалуйста, что тут не так?
Что по вашему происходит с вектором, когда вы делаете push_back ?
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
8Observer8
Гость
« Ответ #19 : Январь 13, 2015, 14:55 »

Если erase, то итератор становится невалидным, напр ++ с ним уже нельзя. Как с auto - не читал, но наверное тоже, т.к. здесь вылетала. Я сделал по-старинке (измененный файл в аттаче), вылета нет
Огромное спасибо! Второй день страдал. Это страшно, когда кажется, что уже никогда её не найдёшь. Я поделюсь кодом игры, когда закончу первый уровень и приведу код в порядок. Как вас отблагодарить? Может пару сотен кинуть на телефон или webmoney? Нормально? Напишите в личку. Не хочу оставаться в долгу. Вы даже не представляете, как вы меня сильно выручили

Кстати, можно написать:

Код
C++ (Qt)
auto iterOfProjectile = m_projectiles.begin();

Вместо:

Код
C++ (Qt)
typedef std::map<int, Projectile*> TMap;
TMap::iterator iterOfProjectile = m_projectiles.begin();
 

Цитировать
Подскажите, пожалуйста, что тут не так?
Что по вашему происходит с вектором, когда вы делаете push_back ?
Зачем говорить загадками? Увеличится размер контейнера. Я не знаю, как внутренее реализован std::vector и сколько памяти он освободит. У меня есть предположение, что первый push_back самый затратный, он выделяет с запасом, чтобы какое-то количество push_back'ов были без выделения, а просто копирование на уже выделенную память. Что-то подобное я читал про QString из раздела "Container Classes" Уверен, что в моей игре, что push_back, что resize(), что обычный массив - погоды не делают
« Последнее редактирование: Январь 13, 2015, 14:58 от 8Observer8 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Январь 13, 2015, 15:09 »

Что по вашему происходит с вектором, когда вы делаете push_back ?
Что-то слишком тонкие намеки Улыбающийся Ну да, перераспределит память, но хранятся-то указатели, поэтому здесь это ничем не чревато.

Как вас отблагодарить?
Не писать поверхностных, непродуманных статей  Улыбающийся

И кстати: если addProjectileExplosion( x0, y0 ) добавляет в мапу (не вижу но в принципе возможно), то вылета не будет, но не все эл-ты будут проитерированы (некоторые новые могут быть пропущены) 
Записан
8Observer8
Гость
« Ответ #21 : Январь 13, 2015, 18:29 »

И кстати: если addProjectileExplosion( x0, y0 ) добавляет в мапу (не вижу но в принципе возможно), то вылета не будет, но не все эл-ты будут проитерированы (некоторые новые могут быть пропущены)  

Я пока не понял, почему могут быть пропущены

Вот здесь ответили что:
Цитировать
Correct would be to use the return value of erase() as the new iterOfProjectile.

Подумаю над этим на досуге

Добавлю пока стенок и сделаю, чтобы можно было взорвать второй танк

Ещё у меня проблемы со звуком. Я хотел сделать отдельный класс SoundOfShot наследником QRunnable и в переопределённом методе run() запускать звуковой эффект выстрела (m_sound это объект класса QSoundEffect):
Код
C++ (Qt)
void SoundOfShot::run()
{
   m_sound.play();
   while ( m_sound.isPlaying() );
}

Объект класса SoundOfShot хотел создавать при нажатии на пробел:

Код
C++ (Qt)
SoundOfShot *sound = new SoundOfShot;
sound->setAutoDelete( true );
QThreadPool::globalInstance()->start( sound );

А перед этим в конструкторе:

Код
C++ (Qt)
QThreadPool::globalInstance()->setMaxThreadCount( 15 );

Идея со звуком и потоками правильная?
« Последнее редактирование: Январь 13, 2015, 18:31 от 8Observer8 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #22 : Январь 14, 2015, 08:50 »

Вот здесь ответили что:
Цитировать
Correct would be to use the return value of erase() as the new iterOfProjectile.
Это предполагает QMap (а там std::map). Впрочем и с QMap цикл for не годится

Ещё у меня проблемы со звуком. Я хотел сделать отдельный класс SoundOfShot наследником QRunnable и в переопределённом методе run() запускать звуковой эффект выстрела (m_sound это объект класса QSoundEffect):
Код
C++ (Qt)
void SoundOfShot::run()
{
   m_sound.play();
   while ( m_sound.isPlaying() );
}
...
Идея со звуком и потоками правильная?
Ну такой run точно неверный, не может класс быть сделан так глупо что его надо так ждать. Что произойдет если, не мудрствуя лукаво, просто вызвать play в главной нитке? Может он асинхронный, и проблемы никакой нет. Для начала проверьте
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.298 секунд. Запросов: 23.