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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Опять накосячил с указателями и объектами. %)  (Прочитано 5035 раз)
Omg
Гость
« : Февраль 08, 2011, 22:03 »

Объясните мне, что я делаю не так. Не надо показывать КАК надо. Объясните что не так. Чтобы я мог сам разобраться. В архиве исходники сервера и клиента. После конекта клиента к серверу, сервер падает.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Февраль 08, 2011, 22:32 »

Как минимум неправильно работаете со списками
Код
C++ (Qt)
void MyServer::slotUpdateUsers  (){
   count=0;
   QTcpSocket *pClient = (QTcpSocket *)sender();
   QList<UserInfo*>::iterator o=user_list->begin();
   for (; o != user_list->end(); ++o){//ищем пользователя
       count++;
       if(user_list->at(count)->uSocket() == pClient){
           user_list->removeAt(count);
       }
   }
   pClient->deleteLater();
}
 
Какой смысл заводить итератор o и брать содержимое списка через user_list->at(count)? Причём всегда на последнем цикле выходите за границы размера списка и пропускаете первый элемент.
Внимательно читайте описание QList в ассистенте:
Цитировать
const T & QList::at ( int i ) const

Returns the item at index position i in the list. i must be a valid index position in the list (i.e., 0 <= i < size()).
Записан

Qt 5.11/4.8.7 (X11/Win)
Omg
Гость
« Ответ #2 : Февраль 08, 2011, 23:10 »

Сменил at на UserInfo* oa= *o, oa->...
и т.д. Не помогло. Как мне кажется проблема не в них.
тем более я нопонимаю, как я могу не брать первый итем, если a++ пост инкремент. Т.е. цикл, начинается с 0 и кончается последним итемом в листе. Единственное, что end возвращает: imaginary item after the last item in the list. А т.к. в условии стоит != то он отсекается. Как я выхожу за рамки и не получаю первый итем?
Записан
Omg
Гость
« Ответ #3 : Февраль 08, 2011, 23:38 »

нашел от чего падает:
как только клиент говорит:
m_pTcpSocket->close();
сервер крашится. %)

disconnectFromHost () тоже самое.

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

Так же если разрывать соединение на сервере. А так все нормально работает, нехватает некоторых опций, но это из-за того, что я мучаюсь с закрытием сокета, который не хочет закрываться. Бен, ай нид хелп. ^^
« Последнее редактирование: Февраль 09, 2011, 00:13 от Omg » Записан
slim
Гость
« Ответ #4 : Февраль 09, 2011, 00:55 »

небольшой совет: старайся освобождать память выделенную через оператор new! лучше конечно используй std::auto_ptr или еще что лучше boost::shared_ptr

edit:
+ не обязательно все хранить в куче, можно и на стеке

ps. на самом деле здесь столько "вкусностей" даже не знаю есть ли смысл продолжать. странно что программа у тебя раньше не упала.
« Последнее редактирование: Февраль 09, 2011, 00:59 от slim » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Февраль 09, 2011, 01:13 »

Попробуйте так
Код
C++ (Qt)
void MyServer::slotUpdateUsers( void )
{
   size_t count = 0;
   QTcpSocket *pClient = (QTcpSocket *)sender();
   while (count < user_list.size()) {
       if(user_list->at(count)->uSocket() == pClient)
           user_list->removeAt(count);
       else
           ++count;
   }
}
 
Записан
Omg
Гость
« Ответ #6 : Февраль 09, 2011, 09:06 »

небольшой совет: старайся освобождать память выделенную через оператор new! лучше конечно используй std::auto_ptr или еще что лучше boost::shared_ptr

edit:
+ не обязательно все хранить в куче, можно и на стеке

ps. на самом деле здесь столько "вкусностей" даже не знаю есть ли смысл продолжать. странно что программа у тебя раньше не упала.
На профессионализм не претендую. Улыбающийся О каких вкусностях вы говорите?

хмм, похоже сервер крашится при попытки удалить сокет:
Код:
  /*  QObject::connect(pClientSocket, SIGNAL(disconnected()   ),
            this,          SLOT(deleteLater()               )
            );*/
в slotNewConnection - если оставлять, то он падает. В чем может быть загвоздка? Или там в чем угодно? Улыбающийся
« Последнее редактирование: Февраль 09, 2011, 09:32 от Omg » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Февраль 09, 2011, 10:16 »

Цитировать
тем более я нопонимаю, как я могу не брать первый итем, если a++ пост инкремент. Т.е. цикл, начинается с 0 и кончается последним итемом в листе. Единственное, что end возвращает: imaginary item after the last item in the list. А т.к. в условии стоит != то он отсекается. Как я выхожу за рамки и не получаю первый итем?
Границы цикла у вас определяются правильно, а обращаетесь к элементам списка вы не через итератор, а через индекс count, который всегда начинается с 1.
Записан

Qt 5.11/4.8.7 (X11/Win)
Omg
Гость
« Ответ #8 : Февраль 09, 2011, 10:23 »

Как он может начинаться с одного, если перед списком идет присваивание 0, а в цикле стоит постинкремент? В случае с преинкрементом, я согласен. Или же в куте как-то меняют пост на пре?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #9 : Февраль 09, 2011, 10:29 »

Цитировать
Как он может начинаться с одного, если перед списком идет присваивание 0, а в цикле стоит постинкремент? В случае с преинкрементом, я согласен. Или же в куте как-то меняют пост на пре?
Цитировать
count++;
if(user_list->at(count)->uSocket() == pClient){
При таком использовании инкремента нет разницы пост он или пре.
Qt тут не причём. Учите C.
Записан

Qt 5.11/4.8.7 (X11/Win)
Omg
Гость
« Ответ #10 : Февраль 09, 2011, 10:40 »

Имеется в виду, что инкремент поучаствовал в выражении a++; а потом вернул увеличенное значение? Ясно. Я думал это распространяется на весь цкл. Улыбающийся бу знать.

Решил проблему след образом:
Код:
connect(pClientSocket, SIGNAL(disconnected()   ),
            this,          SLOT(deleteL()      )
            );
Код:
void MyLogin::deleteL(){
    QTcpSocket* pSocket= (QTcpSocket*)sender();
    pSocket->deleteLater();
}
Так не выдает ошибки. Почему?
« Последнее редактирование: Февраль 09, 2011, 11:05 от Omg » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #11 : Февраль 09, 2011, 10:45 »

Цитировать
Я думал это распространяется на весь цкл.
Хм, я бы на вашем месте имея такие серьёзные пробелы в знаниях о программировании отложил бы в сторону написание сложных программ, тем более client-server-ных и взался за чтение книг.
Записан

Qt 5.11/4.8.7 (X11/Win)
Omg
Гость
« Ответ #12 : Февраль 09, 2011, 11:07 »

А я бы на вашем месте, не давал советов, которые не просят. Улыбающийся По одним книгам ничего не узнаешь.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #13 : Февраль 09, 2011, 11:11 »

Цитировать
По одним книгам ничего не узнаешь.
Согласен, но учить язык при написании client-server-a мне кажется это слишком круто)
Записан

Qt 5.11/4.8.7 (X11/Win)
Omg
Гость
« Ответ #14 : Февраль 09, 2011, 11:16 »

Это уже позвольте мне решать. Улыбающийся Спасибо. Лучше объясните, почему переопределение deleteLater(); убрало ошибку. Улыбающийся
Сам разобрался. Не на то указатель стоял в соединении сигнала и слота... Смеющийся Он патался удалить объект логин, а не сокет.  Смеющийся
« Последнее редактирование: Февраль 09, 2011, 11:42 от Omg » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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