Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
koker007
14 / 17 / 1
Регистрация: 04.08.2015
Сообщений: 311
Завершенные тесты: 2
#1

Разные значения в дебаге и релизе - C++

23.02.2017, 15:47. Просмотров 857. Ответов 43
Метки нет (Все метки)

В общем в чем суть, пишу игру, участок сетевого кода написан с помощью sfml.
В дебаге программа не работает, потому что изходящие и входяшие пакеты различаются по размеру. В релизе размер пакетов совпадает и сеть работает. По этому приходится отлаживать в релизе. Но проблема в том что приходит не верное значение.
В дебаге, на отправку значение запаковывается верное, а в релизе не могу проследить этот момент, именно момент упаковки значения в пакет, отладчик пропускает этот код. Я знаю что он пропускает код из-за сжатия кода и "ненужный" по мнению отладчика выкидывается, однако в дебаге я не могу проверить какое бы значение пришло, т.к. размер исхояшего и входяшего пакета разные и пакет забраковывается.

Разные значения в дебаге и релизе

Я думаю что этот участок забраковывается потому что отладчик не может установить дальнейшую связь в использовании этого значения. Потому что далее связь устанаваливается, с дальнейшим кодом программы, через интернет. Я объявил ключевую переменную как volatile, в настройках проекта поставил "без оптимизации всей программы", однако он продолжает пропускать этот участок.

Объясните пожалуйста, как это можно решить?
Объясните хотя бы причины такого странного поведения, если я не прав в своих догадках, очень надеюсь на ваше понимание, это мой первый проект.
http://www.cyberforum.ru/cpp-beginners/thread1491866.html
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.02.2017, 15:47
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Разные значения в дебаге и релизе (C++):

Программа при релизе не работает, а при дебаге работает
#include<iostream>; #include <iomanip> #include<fstream> using namespace...

Отладчик VS показывает разные значения
При отладке постоянно встречаюсь с такой фигнёй: до входа в какую-либо...

Где ошибка? выдает разные значения
#include<iostream> #include<iomanip> #include<cmath> using namespace std;...

В дебагере всё ок в релизе нет
Добрый день, такая вот интересная проблема. Есть задача. Есть картинки по...

Как сделать так, чтобы функция rand() возвращала разные значения
Добрый вечер, как можно в visual studio в цикле каждый раз задавать новые...

43
nd2
2828 / 2398 / 1052
Регистрация: 29.01.2016
Сообщений: 8,022
23.02.2017, 15:51 #2
Лучший ответ Сообщение было отмечено koker007 как решение

Решение

Цитата Сообщение от koker007 Посмотреть сообщение
В дебаге программа не работает, потому что изходящие и входяшие пакеты различаются по размеру.
Цитата Сообщение от koker007 Посмотреть сообщение
Объясните пожалуйста, как это можно решить?
Сделать чтобы не различались. Если код без ошибок, то и в debug всё должно работать. Если не работает - значит код кривой, и то, что он работает в релиз, этого не меняет.
1
hoggy
Заблокирован
23.02.2017, 16:53 #3
Цитата Сообщение от koker007 Посмотреть сообщение
В дебаге программа не работает, потому что изходящие и входяшие пакеты различаются по размеру.
потому что написанна криво и содержит ошибку.
ищите и исправляйте.

Цитата Сообщение от koker007 Посмотреть сообщение
В релизе размер пакетов совпадает и сеть работает.
к вашему несчастью так совпали звезды.
было бы лучше, когда в случае багов релиз тоже не работает.

Цитата Сообщение от koker007 Посмотреть сообщение
Я думаю что этот участок забраковывается потому что отладчик
пошагово отлаживаться нужно в дебаге.
релиз - оптимизирован
(исполняемый код и данные могут не соответствовать ожидаему согласно исходному коду)
2
koker007
14 / 17 / 1
Регистрация: 04.08.2015
Сообщений: 311
Завершенные тесты: 2
28.02.2017, 11:44  [ТС] #4
Вы оба были правы, спасибо, я нашел саму ошибку в дебаге, но пока не выяснил причину ее появления.

Участок кода в котором ошибка такой:
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
                    //Пакет в любом случае является исходяшим. проверка не нужна
                    //Если пакет готов - отправляем
                    if(pack[numer]->get_ready() == 1){
                        //то отправляем его
                        unsigned short port = 45666;
                        sf::IpAddress ip_in = pack[numer]->get_ip(); //возвращяет string
                        /*
                        if (pack[numer]->get_port() != 0){
                            port = pack[numer]->get_port();
                        }
                        */
                        //sf::IpAddress ip_local = sf::IpAddress::getLocalAddress();
 
                        sf::UdpSocket func_sock;
                        func_sock.bind(port);
 
                        if (pack[numer]->get_num_send() < 1){
                            GLushort time_num = pack[numer]->get_num_send();
                            pack[numer]->plus_num_send();
 
                            sf::IpAddress ip_local = sf::IpAddress::getLocalAddress();
 
                            sf::Packet packet_sf_out;
                            packet_sf_out.append(pack[numer], sizeof(packet));
 
                            sf::Socket::Status status;
                            status = func_sock.send(packet_sf_out, ip_in, port);
 
                            if (status == sf::Socket::Status::Done && setup_game_session.get_pack_out_y_n(pack[numer]->get_id()) == 0){
                                setup_game_session.set_pack_out_y_n(pack[numer]->get_id(), 1);
                                cout << "Socket out: ID " << pack[numer]->get_id() << '\n';
 
                            }
                            else if (status == sf::Socket::Status::Disconnected){
                                cout << "Socket out: Status::Disconnected" << '\n';
                            }
                            else if (status == sf::Socket::Status::Error){
                                cout << "Socket out: Status::Error" << '\n';
                            }
                            else if (status == sf::Socket::Status::NotReady){
                                cout << "Socket out: Status::NotReady" << '\n';
                            }
                            else if (status == sf::Socket::Status::Partial){
                                cout << "Socket out: Status::Partial" << '\n';
                            }
                        }
                        //Иначе если время жизни пакета потрачено
                        else{
                            delete pack[numer];
                            //подчишаем указатель
                            pack[numer] = 0;
                            
                            sum_pack--;
                            //set_max_socket(get_max_socket() - 1);
                        }
                    }
результат
status == sf::Socket::Status::Error
К сожалению в sfml не написанны возможные причины этого статуса.
Но я думаю что функции func_sock.send(packet_sf_out, ip_in, port) которая его возвращает, не нравится какая-то одна из переменных, странно что она в принципе их все принимает. Я надеюсь ход мыслей у меня правильный, поправьте, если нет.

Добавлено через 2 часа 3 минуты
В общем вся проблема оказалась в ip.

Так работает
C++
1
sf::IpAddress ip_in("192.168.1.116");
Так нет
C++
1
2
string ip_str = "192.168.1.116";
sf::IpAddress ip_in(ip_str);
Почему? И как это лечится?

мне кажется что у sf::IpAddress вызывается не правильный конструктор, честно говоря до сих-пор запинаюсь с & и *.
У sf::IpAddress такие конструкторы:
C++
1
2
3
sf::IpAddress::IpAddress(const std::string & address)
sf::IpAddress::IpAddress(const char * address)
sf::IpAddress::IpAddress(Uint32 address)
0
nd2
2828 / 2398 / 1052
Регистрация: 29.01.2016
Сообщений: 8,022
28.02.2017, 13:51 #5
Цитата Сообщение от koker007 Посмотреть сообщение
Так нет
Если так?
C++
1
2
string ip_str = "192.168.1.116";
sf::IpAddress ip_in(ip_str.c_str());
0
nmcf
6237 / 5549 / 2524
Регистрация: 14.04.2014
Сообщений: 23,337
28.02.2017, 14:06 #6
А зачем вообще использовать строки? Там же есть числовой конструктор - четыре числа.
0
nd2
2828 / 2398 / 1052
Регистрация: 29.01.2016
Сообщений: 8,022
28.02.2017, 14:12 #7
Цитата Сообщение от nmcf Посмотреть сообщение
А зачем вообще использовать строки?
А почему не использовать, раз есть конструктор? Вопрос в другом: почему со std::string не работает.
1
nmcf
6237 / 5549 / 2524
Регистрация: 14.04.2014
Сообщений: 23,337
28.02.2017, 14:13 #8
Он что-то неправильно делает.
0
nd2
2828 / 2398 / 1052
Регистрация: 29.01.2016
Сообщений: 8,022
28.02.2017, 14:16 #9
Цитата Сообщение от nmcf Посмотреть сообщение
Он что-то неправильно делает.
Возможно.
0
koker007
14 / 17 / 1
Регистрация: 04.08.2015
Сообщений: 311
Завершенные тесты: 2
28.02.2017, 14:48  [ТС] #10
Решил сделать так:
C++
1
2
    string ip_str = pack[numer]->get_ip();
    sf::IpAddress ip_in(ip_str.c_str());
Отправляется.
Спасибо, но я чуть раньше догадался)


Однако при приеме пакета, когда вытаскивается ip отправителя из sf::IpAddress ip_out методом ip_out.toString()
выскакивает ошибка нарушения прав доступа.

Код обработки входящих пакетов:
ошибка в 38 строке
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
                    //Создаем пакет sf для приема
                    sf::Packet packet_sf_in;
 
                    //Получаем ip отправителя
                    sf::IpAddress ip_out;
                    //порт отправителя
                    unsigned short port;
                    sf::UdpSocket  packet_sf;
 
                    //прослушиваемый порт
                    packet_sf.bind(45666);
 
                    //Не блокируюший режим прослушивания
                    packet_sf.setBlocking(0);
 
                    //запомним старый id пакета
                    GLushort old_id = pack[numer]->get_id();
 
                    //Номер попытки прослушивания
                    GLushort num_try = 0;
 
                    sf::Socket::Status status = sf::Socket::Status::NotReady;
 
                    //Слушаем, пока попытки не кончелись или пакет не получен
                    for (num_try = 0; num_try < 1000 && status == sf::Socket::Status::NotReady; num_try++){
                        status = packet_sf.receive(packet_sf_in, ip_out, port);
                    }
                    
                    //Если пакет получен
                    if (status == sf::Socket::Status::Done){
                        //Если размер данных совпадает
                        if (sizeof(packet) == packet_sf_in.getDataSize()){
                            //Заносим данные из пакета
                            packet* pointer_data_packet_sf = ((packet*)packet_sf_in.getData());
                            pack[numer]->operator=(pointer_data_packet_sf);
 
                            string ip_str;
                            ip_str = ip_out.toString();
 
                            //сохраняем ip пакета
                            pack[numer]->set_ip(ip_str);
                            pack[numer]->set_port(GLushort(port));
 
                            //проверяем есть ли полученный ip в списке
                            GLbyte ok_ip = 0;
                            GLushort player_id = 0;
 
                            for(GLushort id = 0; id < 10 && ok_ip == 0; id++){
                                if (setup_game_session.get_ip(id) == pack[numer]->get_ip()){
                                    ok_ip = 1;
                                    player_id = id;
                                }
                            }
 
                            //Если айпи так и не был найден, проверяем, это Ip сервера или нет
                            GLbyte ip_server_y_n = 0;
                            if(ok_ip == 0 && setup_game_session.get_ip_server() == pack[numer]->get_ip()){
                                ip_server_y_n = 1;
                                ok_ip = 1;
                            }
 
                            //Если есть то проверяем был ли пакет с таким id уже получен
                            if(ok_ip == 1){
                                //если не был
                                if(ip_server_y_n == 0 && setup_game_session.get_pack_received(player_id, pack[numer]->get_id()) == 0){
                                    //Говорим что пакет уже получен
                                    setup_game_session.set_pack_received(player_id, pack[numer]->get_id(), 1);
 
                                    //обнуляем время ожидания
                                    setup_game_session.null_timeout_client(player_id);
 
                                    GLuint pack_id = pack[numer]->get_id();
 
                                    //то разпаковываем его
                                    UNZIP_packet(numer);
                                    //Удаляем пакет
                                    delete pack[numer];
                                    //создаем пакет пустышку
                                    pack[numer] = new packet(1, 'i', 1);
 
                                    cout << "Socket in: ID " << pack_id <<'\n';
                                }
                                else if((ip_server_y_n == 1) && (setup_game_session.get_pack_out_y_n(pack[numer]->get_id()) == 0)){
                                    setup_game_session.set_pack_out_y_n(pack[numer]->get_id(), 1);
 
                                    GLuint pack_id = pack[numer]->get_id();
 
                                    //то разпаковываем его
                                    UNZIP_packet(numer);
                                    //Удаляем пакет
                                    delete pack[numer];
                                    //создаем пакет пустышку
                                    pack[numer] = new packet(1, 'i', 1);
 
                                    cout << "Socket in: ID " << pack_id << '\n';
                                }
                                //Иначе пакет уже приходил
                                else{
                                    GLuint id_pack = pack[numer]->get_id();
                                    delete pack[numer];
                                    pack[numer] = new packet(old_id, 'i', 1);
                                    //cout << "Socket in: ID " << id_pack << " deleted" << '\n';
                                }
                            }
                            else{
                                if(setup_game_session.get_server_y_n() == 1){
 
                                    GLuint pack_id = pack[numer]->get_id();
 
                                    //то разпаковываем его
                                    UNZIP_packet(numer);
                                    //Удаляем пакет
                                    delete pack[numer];
                                    //создаем пакет пустышку
                                    pack[numer] = new packet(1, 'i', 1);
 
                                    cout << "Socket in: ID " << pack_id << " first connect" << '\n';
                                }
                            }
 
                        }
                        else{
                            cout << "Socket in: BAD SIZE PACKET; delete pack" << '\n';
                            delete pack[numer];
                            pack[numer] = new packet(old_id, 'i', 1);
                        }
                    }
Получается все та-же проблема, sf::IpAddress почему-то не дружит с string. Странно что в релизе этот момент проходит.

Добавлено через 4 минуты
Цитата Сообщение от nmcf Посмотреть сообщение
А зачем вообще использовать строки? Там же есть числовой конструктор - четыре числа.
Как не крути, но со строками удобнее, не нужно конвертировать в число. Просто в игре пользователь набирает ip подключения строкой.
Строка она же, именно для этого и была придумана, чтобы не приходилось каждый символ записывать отдельно в массив, иначе говоря - чтобы было проще.
0
nmcf
6237 / 5549 / 2524
Регистрация: 14.04.2014
Сообщений: 23,337
28.02.2017, 15:01 #11
А у тебя версия SFML соответствует компилятору? Настройки правильные? Там же отдельные lib для debug и release.
1
koker007
14 / 17 / 1
Регистрация: 04.08.2015
Сообщений: 311
Завершенные тесты: 2
28.02.2017, 15:13  [ТС] #12
Цитата Сообщение от nmcf Посмотреть сообщение
А у тебя версия SFML соответствует компилятору?
Я все стараюсь через cmake собирать, но касательно sfml не помню, сейчас перепроверю все, тоже думаю в ней проблема.
0
nmcf
28.02.2017, 15:34
  #13

Не по теме:

Не Windows, что ли?

0
koker007
14 / 17 / 1
Регистрация: 04.08.2015
Сообщений: 311
Завершенные тесты: 2
28.02.2017, 15:48  [ТС] #14
Цитата Сообщение от nmcf Посмотреть сообщение
Там же отдельные lib для debug и release.
Был только релиз подключен, для дебага и релиза, теперь игра на втором пк жалуется на отсутствие MSVCP140D.dll
На втором пк установлен vcredist. Не могу теперь отправить запрос о подключении. Игра одновременно и сервер и клиент, если запустить на одном пк 2 раза, то будет конфликт портов.
Я бы попробовал кидать MSVCP140D.dll и другие файлы которые он будет продолжать дальше требовать, но это очень наврятли закончится успехом. Понимаю что проблема тут скорей всего была именно в том что я использовал релиз sfml в дебаге.
Но теперь то как заставить работать дебаг версию на другом пк? придется полностью устанавливать VS?

Добавлено через 1 минуту
Цитата Сообщение от nmcf Посмотреть сообщение
Не Windows, что ли?
Виндовс, просто при сборке через cmake там предлагаются дополнительные опции, которые, бывает иногда желательно не пропускать.
0
nmcf
6237 / 5549 / 2524
Регистрация: 14.04.2014
Сообщений: 23,337
28.02.2017, 16:27 #15
Цитата Сообщение от koker007 Посмотреть сообщение
На втором пк установлен vcredist
Может, версия не та? Там как минимум 6 видов с 2005 по 2015 плюс разрядность.
0
koker007
14 / 17 / 1
Регистрация: 04.08.2015
Сообщений: 311
Завершенные тесты: 2
28.02.2017, 16:41  [ТС] #16
Цитата Сообщение от nmcf Посмотреть сообщение
Может, версия не та?
Я ее брал из папки Microsoft Visual Studio 14.0\VC\redist\1033\vcredist_x86.exe
так что, это очень наврятли.
Если бы это было так, то и релиз бы не запускался
0
hoggy
Заблокирован
01.03.2017, 10:49 #17
Цитата Сообщение от koker007 Посмотреть сообщение
Однако при приеме пакета, когда вытаскивается ip отправителя из sf::IpAddress ip_out методом ip_out.toString()
выскакивает ошибка нарушения прав доступа.
ну значит ip_out - битый.

смотрите в отладчике его состояние.

ну и что будет с ip_out если попытки кончились?
C++
1
2
3
4
//Слушаем, пока попытки не кончелись или пакет не получен
for (num_try = 0; num_try < 1000 && status == sf::Socket::Status::NotReady; num_try++){
    status = packet_sf.receive(packet_sf_in, ip_out, port);
}
0
koker007
14 / 17 / 1
Регистрация: 04.08.2015
Сообщений: 311
Завершенные тесты: 2
01.03.2017, 12:54  [ТС] #18
Цитата Сообщение от hoggy Посмотреть сообщение
ну и что будет с ip_out если попытки кончились?
Если закончатся попытки то status == sf::Socket::Status::NotReady и программа пропустит тот участок где ip_out используется.


Установил VS2015 на второй пк, со второго раза запустилась дебаг версия (на первый раз была ошибка отсутствия uctrbased.dll, решилась полной переустановкой VS2015)
При отправке пакета с дебаг версии 2-го пк на дебаг версию 1-го пк, возникает все таже ошибка, все в том-же месте, при попытке перевода ipAddress в string. Были подключены дебаг либы SFML, но это проблему не решило.

Разные значения в дебаге и релизе

Проблема видно не стандартная, но вы бы что сделали?
0
koker007
14 / 17 / 1
Регистрация: 04.08.2015
Сообщений: 311
Завершенные тесты: 2
01.03.2017, 13:34  [ТС] #19
Разные значения в дебаге и релизе
0
hoggy
Заблокирован
01.03.2017, 14:27 #20
Цитата Сообщение от koker007 Посмотреть сообщение
При отправке пакета с дебаг версии 2-го пк на дебаг версию 1-го пк, возникает все таже ошибка, все в том-же месте, при попытке перевода ipAddress в string.
какое именно слово в следующей фразе было не понятно?
Цитата Сообщение от hoggy Посмотреть сообщение
ну значит ip_out - битый.
в дебаге срабатывает защита кучи.
такое бывает, при попытке использовать неинициализированный/неконсистентный объект.

на вашем месте я бы уже давно забрякался на строке:
Цитата Сообщение от koker007 Посмотреть сообщение
ip_str = ip_out.toString();
убедился бы - да, объект действительно в кашу.
а дальше уже смотрел бы, в отладчике: где объёт ещё жив,
и где он уже запорчен.
1
01.03.2017, 14:27
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.03.2017, 14:27
Привет! Вот еще темы с решениями:

Непонятный глюк при дебаге
Курсор стоял на 200-й строке, я добавил Buffer в Watch и сразу вылезло окно...

Сделать программу которая будет записывать разные значения в переменную типа integer
Пользователь должен вводить различные параметры, например количество масок = 3,...

На засыпку для новичков: в функции передаётся один параметр, а его значения разные; почему?
#include &lt;stdio.h&gt; //Тут некоторый код void foo(X* pX) {printf (&quot;%x\n&quot;,...

При релизе программы не падают фигуры по таймеру
Извините, если тема повторяется, но при отладке приложения все нормально(в моем...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru