Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 5.00
Preveter
9 / 9 / 1
Регистрация: 11.08.2011
Сообщений: 66
#1

Непонятный баг - C++

11.08.2011, 22:15. Просмотров 1369. Ответов 14
Метки нет (Все метки)

Пишу программу на Си++ с использованием Qt и FMOD.

Вот место, где глючит (тут только куски кода, не весь):
C++ (Qt)
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
void SWSaver::load(std_units* sUnits,swmap *map, int *unitsNum, SWUnit *units, int *playerNum,
                   SWPlayer *players,int *turnPlayer, int **resources){
    QString filename = QFileDialog::getOpenFileName(NULL,("Сохранение игры"), (""), ("SWSave (*.sws)"));
    QByteArray ar = filename.toAscii();
    char* name=ar.data();
 
    int i,j,w,h;
 
    FILE* file = fopen(name,"r");
 
// ...
 
    int a;
 
    fread(&a,sizeof(int),1,file);
    *playerNum=a;
    players=new SWPlayer[*playerNum];
 
    for(i=0;i<*playerNum;i++){
        int b;
        QString tempS;
        fread(&tempS,sizeof(QString),1,file);
        fread(&a,sizeof(int),1,file);
        players[i].setNameAndNum(tempS,a);
// ...
    }
 
    for(i=0;i<*playerNum;i++){
        ar = players[i].name.toAscii();
        name=ar.data();
        fprintf(bug,"(%d)%s(%d)\n",i,name,players[i].aliance);
        fflush(bug);
    }
    fclose(file);
// ...
}
 
 
void Window::menu_LoadGame(){
// ...
    swmap* mapL;
    int unitsNumL;
    SWUnit* unitsL;
    int playerNumL;
    SWPlayer* playersL;
    int turnPlayerL;
    int** resMaskL;
    saver.load(&field->stdUnits,mapL,&unitsNumL,unitsL,&playerNumL,playersL,&turnPlayerL,resMaskL);
 
    QByteArray ar;
    char* name;
 
    // здесь программа ещё живёт
 
    for(i=0;i<playerNumL;i++){
        // а до сюда не доживает
        ar = playersL[i].name.toAscii();
        name=ar.data();
        fprintf(bug,"--(%d)%s\n",i,name);
        fflush(bug);
    }
// ...
}
В чём дело, подскажите пожалуйста...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.08.2011, 22:15
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Непонятный баг (C++):

Баг asio? или баг TCP стека? - C++
всем привет. повстречался с очень странным багом. и не могу определить кто бажит, asio, или TCP-стек. на стороне клиента,...

очень интересный баг - C++
Если кто-нибудь догадается в чем ошибка, то скажите. Ошибку я уже исправил, но не знаю, почему не работает этот код: #include...

Устал искать баг - C++
Проблемма проста - нужно удалить из вещественной матрицы строку и столбец, верней ряд строк и столбцов (условие - нулевой элемент на...

Баг в MinGW при использовании fread - C++
Ну собственно вот простой тестовый код который выполняется некорректно: #include &lt;cstdio&gt; using namespace std; const int N =...

Помогите выловить баг, сил моих больше нету((( - C++
Программа глючит при добавлении больших структурированных каталогов, раньше думал, что ошибка выделения памяти, оказалось нет...Очень надо...

Баг или так задумано? Фишка с кодировкой файлов компиляции - C++
Visual C++ 2013 Express. От изменения кодировки созданных .cpp файлов будет зависеть то как выводятся русские буквы. Никогда раньше не...

14
voral
455 / 436 / 68
Регистрация: 16.03.2008
Сообщений: 2,130
12.08.2011, 01:06 #2
1. Используйте теги форматирования!!! Они не для красоты
2. Расшифруйте, что значит "здесь программа ещё живёт" и "не доживает". что происходит? Что выводит в консоль? Как определили, что именно до этого места не доживает?
0
soft.creator
104 / 104 / 4
Регистрация: 17.10.2010
Сообщений: 283
12.08.2011, 08:54 #3
Есть подозрение, что playerNumL равен нулю.
Поэтому цикл не выполняется ни разу.

Цитата Сообщение от voral Посмотреть сообщение
1. Используйте теги форматирования!!! Они не для красоты
+1
0
Preveter
9 / 9 / 1
Регистрация: 11.08.2011
Сообщений: 66
12.08.2011, 18:00  [ТС] #4
Извиняюсь, комментарий "а до сюда не доживает" (в том месте где стоит этот комментарий программа уже не работает - она вылетает раньше) надо было расположить на строчку ниже. При этом playerNumL не равно 0 (оно в моём случае равно двойке) и программа вылетает на первой строчке из цикла, т.е. если поставить вывод перед строкой №29 и после, то перед - выведет, а после - нет...

В SWSaver я делал вывод значений "playersL[i].name". Там всё было нормально, а здесь не хочет...

PS Извиняюсь за неотформатированый текст в первом сообщении. Когда писал - торопился...
0
voral
455 / 436 / 68
Регистрация: 16.03.2008
Сообщений: 2,130
12.08.2011, 18:20 #5
Цитата Сообщение от Preveter Посмотреть сообщение
т.е. если поставить вывод перед строкой №29 и после, то перед - выведет, а после - нет...
Наверное 57 строка?
Вообще, что то в консоль выдает при крахе?
Попробуйте закоментировать все тело цикла и поставить
C++
1
qDebug() << i;



Добавлено через 7 минут
А что такое "bug" точнее как создаете, что делаете с ней до этого?
0
Preveter
9 / 9 / 1
Регистрация: 11.08.2011
Сообщений: 66
12.08.2011, 18:37  [ТС] #6
Цитата Сообщение от voral Посмотреть сообщение
Наверное 57 строка?
Да, вы правы.

Цитата Сообщение от voral Посмотреть сообщение
Вообще, что то в консоль выдает при крахе?
programm.exe завершился с кодом -1073741819 (Программирую в QtCreator)

Цитата Сообщение от voral Посмотреть сообщение
А что такое "bug" точнее как создаете, что делаете с ней до этого?
Это переменная типа FILE* (локальная).
C++
1
2
FILE* bug;
bug=fopen("bug.log","w");
Добавлено через 9 минут
Закомментировал тело цикла. Вместо него намисал вывод текущёго i. Он проходит весь цикл и вылетает на следующем обращении к playersL[i].name.

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
...................
    QByteArray ar;
    char* name;
 
    for(i=0;i<playerNumL;i++){  // <- это закомментированный цикл
        fprintf(bug,"+==%d",i);  // <- вот вывод
        fflush(bug);
//        ar = playersL[i].name.toAscii();
//        name=ar.data();
//        fprintf(bug,"--(%d)%s\n",i,name);
//        fflush(bug);
    }
 
    playerNum=playerNumL;
    delete[] players;
    players = new SWPlayer[playerNum]();
    for (i=0;i<playerNum;i++){
        fprintf(bug,"->9-players - step 2 [%d/%d]\n",i,playerNum);
        fflush(bug);
        QString tempS=playersL[i].name;     // <- В таком случае вылетает тут, что по сути логично...
        fprintf(bug,"4\n");
        fflush(bug);
......................
    }
0
soft.creator
104 / 104 / 4
Регистрация: 17.10.2010
Сообщений: 283
12.08.2011, 19:25 #7
Блин, только сейчас заметил - playersL указывает в никуда.
Вы его передаете в функцию load по значению. Функция модифицирует свой параметр, но при этом переменная playersL остается неизмененной. Вам нужно передать ссылку на этот указатель, то есть void SWSaver::load(std_units* sUnits,swmap *map, int *unitsNum, SWUnit *units, int *playerNum, SWPlayer *&players, int *turnPlayer, int **resources). Тогда все будет тип-топ
1
Preveter
9 / 9 / 1
Регистрация: 11.08.2011
Сообщений: 66
12.08.2011, 19:49  [ТС] #8
Цитата Сообщение от soft.creator Посмотреть сообщение
SWPlayer *&players
Эмммм... Третий год программирую на Си++, и причём уже достаточно хорошо, а ни разу такого не встечал... ЧТО ЭТО???

PS до этого 5 лет программировал на Basic'е. Потом сообразил, что это фигня и перешёл на Си++

Добавлено через 4 минуты
Что такое ссылка в Си++ я знаю. А вот Как это работает тут???

Ведь "*&players" это вроде бы всё равно что "players"?!
0
grizlik78
Эксперт С++
1957 / 1450 / 116
Регистрация: 29.05.2011
Сообщений: 3,012
12.08.2011, 20:25 #9
Цитата Сообщение от Preveter Посмотреть сообщение
Ведь "*&players" это вроде бы всё равно что "players"?!
Это если & означает взятие адреса, то да. Но здесь-то & участвует в объявлении переменной, а значит он относится к типу и означает как раз ссылку. Указатели, как и любые другие переменные, наряду с передачей по значению могут сами передаваться по указателю или по ссылке. Вот здесь и объявляется передача указателя на SWPlayer по ссылке.
1
Preveter
9 / 9 / 1
Регистрация: 11.08.2011
Сообщений: 66
12.08.2011, 20:32  [ТС] #10
И как тогда мне нужно изменить вызов функции??? (строка 48 в первом сообщении)

Как мне передать ссылку на уже существующий указатель?
0
grizlik78
Эксперт С++
1957 / 1450 / 116
Регистрация: 29.05.2011
Сообщений: 3,012
12.08.2011, 20:42 #11
А вызов функции в этом случае изменять не надо. Изменяется только прототип функции.
0
Preveter
9 / 9 / 1
Регистрация: 11.08.2011
Сообщений: 66
12.08.2011, 20:47  [ТС] #12
Изменил объявление и инициализацию функции так, как сказал soft.creator, но вызов не менял. И всё заработало. 0_0

Объясните, пожалуйста, в чём дело...
0
grizlik78
Эксперт С++
1957 / 1450 / 116
Регистрация: 29.05.2011
Сообщений: 3,012
12.08.2011, 20:52 #13
Ну вот упрощённый пример. Первая функция меняет локальную копию указателя, вторая же меняет сам указатель.
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
#include <iostream>
 
using namespace std;
 
void fn1(int* p)
{
    p = NULL;
}
 
void fn2(int *& p)
{
    p = NULL;
}
 
int main()
{
    int var;
    int *ptr = &var;
    cout << "ptr:" << ptr << endl;
    fn1(ptr);
    cout << "ptr:" << ptr << endl;
    fn2(ptr);
    cout << "ptr:" << ptr << endl;
}
Есть что непонятного?
1
voral
455 / 436 / 68
Регистрация: 16.03.2008
Сообщений: 2,130
12.08.2011, 23:50 #14
Тут наверное для наглядности можно было бы так "разнести"
C++
1
2
3
4
void fn2(int* &p)
{
    p = NULL;
}
Т.е. p это "синоним" передаваемого параметра типа int*
0
soft.creator
104 / 104 / 4
Регистрация: 17.10.2010
Сообщений: 283
13.08.2011, 07:20 #15
Цитата Сообщение от voral Посмотреть сообщение
Тут наверное для наглядности можно было бы так "разнести"
C++
1
2
3
4
void fn2(int* &p)
{
    p = NULL;
}
Т.е. p это "синоним" передаваемого параметра типа int*
Именно. Можно, конечно, и по-сишному сделать:
C++
1
2
3
4
void fn2(int** p)
{
    *p = NULL;
}
Но это ИМХО менее наглядно, да и при вызове придется & перед указателем ставить.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.08.2011, 07:20
Привет! Вот еще темы с ответами:

Непонятный оператор if - C++ Builder
Как так происходит? В чем я туплю? Почему при authorizedUser == 1 (как показывает вочлист), в выражении if (authorizedUser &gt; 0)...

Непонятный вывод на форму - C++ Builder
Выводит на форму данные из переменной на форму, вместо текста, который надо. В коде, который ниже я скину причину, но как исправить не...

Баг в MonthDays - C++ Builder
узнаю кол-во дней в феврале: MonthDays Он пишет что их 31, но на самом деле 28, ни в один год он не попадает с результатом :( Может...

Непонятный баг в ListView - Программирование Android
В общем, суть такова: Имеется список контактов в ListView. Каждый пункт содержит аватарку, имя и телефон. Адаптер ListView: ...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
13.08.2011, 07:20
Ответ Создать тему
Опции темы

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