Russian Qt Forum

Программирование => С/C++ => Тема начата: Omg от Февраль 08, 2011, 22:03



Название: Опять накосячил с указателями и объектами. %)
Отправлено: Omg от Февраль 08, 2011, 22:03
Объясните мне, что я делаю не так. Не надо показывать КАК надо. Объясните что не так. Чтобы я мог сам разобраться. В архиве исходники сервера и клиента. После конекта клиента к серверу, сервер падает.


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: GreatSnake от Февраль 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()).


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


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: Omg от Февраль 08, 2011, 23:38
нашел от чего падает:
как только клиент говорит:
m_pTcpSocket->close();
сервер крашится. %)

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

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

Так же если разрывать соединение на сервере. А так все нормально работает, нехватает некоторых опций, но это из-за того, что я мучаюсь с закрытием сокета, который не хочет закрываться. Бен, ай нид хелп. ^^


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: slim от Февраль 09, 2011, 00:55
небольшой совет: старайся освобождать память выделенную через оператор new! лучше конечно используй std::auto_ptr или еще что лучше boost::shared_ptr

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

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


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: Igors от Февраль 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;
   }
}
 


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: Omg от Февраль 09, 2011, 09:06
небольшой совет: старайся освобождать память выделенную через оператор new! лучше конечно используй std::auto_ptr или еще что лучше boost::shared_ptr

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

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

хмм, похоже сервер крашится при попытки удалить сокет:
Код:
  /*  QObject::connect(pClientSocket, SIGNAL(disconnected()   ),
            this,          SLOT(deleteLater()               )
            );*/
в slotNewConnection - если оставлять, то он падает. В чем может быть загвоздка? Или там в чем угодно? :)


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


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: Omg от Февраль 09, 2011, 10:23
Как он может начинаться с одного, если перед списком идет присваивание 0, а в цикле стоит постинкремент? В случае с преинкрементом, я согласен. Или же в куте как-то меняют пост на пре?


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: GreatSnake от Февраль 09, 2011, 10:29
Цитировать
Как он может начинаться с одного, если перед списком идет присваивание 0, а в цикле стоит постинкремент? В случае с преинкрементом, я согласен. Или же в куте как-то меняют пост на пре?
Цитировать
count++;
if(user_list->at(count)->uSocket() == pClient){
При таком использовании инкремента нет разницы пост он или пре.
Qt тут не причём. Учите C.


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: Omg от Февраль 09, 2011, 10:40
Имеется в виду, что инкремент поучаствовал в выражении a++; а потом вернул увеличенное значение? Ясно. Я думал это распространяется на весь цкл. :) бу знать.

Решил проблему след образом:
Код:
connect(pClientSocket, SIGNAL(disconnected()   ),
            this,          SLOT(deleteL()      )
            );
Код:
void MyLogin::deleteL(){
    QTcpSocket* pSocket= (QTcpSocket*)sender();
    pSocket->deleteLater();
}
Так не выдает ошибки. Почему?


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: GreatSnake от Февраль 09, 2011, 10:45
Цитировать
Я думал это распространяется на весь цкл.
Хм, я бы на вашем месте имея такие серьёзные пробелы в знаниях о программировании отложил бы в сторону написание сложных программ, тем более client-server-ных и взался за чтение книг.


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: Omg от Февраль 09, 2011, 11:07
А я бы на вашем месте, не давал советов, которые не просят. :) По одним книгам ничего не узнаешь.


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: GreatSnake от Февраль 09, 2011, 11:11
Цитировать
По одним книгам ничего не узнаешь.
Согласен, но учить язык при написании client-server-a мне кажется это слишком круто)


Название: Re: Опять накосячил с указателями и объектами. %)
Отправлено: Omg от Февраль 09, 2011, 11:16
Это уже позвольте мне решать. :) Спасибо. Лучше объясните, почему переопределение deleteLater(); убрало ошибку. :)
Сам разобрался. Не на то указатель стоял в соединении сигнала и слота... ;D Он патался удалить объект логин, а не сокет.  ;D