| 
				
				Изменяется переменная
				 | 
 | 
| kalumb | Дата: Воскресенье, 15 Декабря 2019, 17:38 | Сообщение # 1 |  
| 
 почетный гость 
Сейчас нет на сайте 
 
 | Всем привет. У меня что-то странное происходит с переменной. Она изменяется в зависимости он вызова других функций. Код на картинке. Ситуация такая. Функция LoadFile возвращает буфер с прочитанным файлом и записывает в переменную BufferSize его размер. Но потом почему-то эта переменная меняется сама собой. Если в коде оставить функцию printf в зелёной рамке, то переменная изменяется (Вывод 1), а если убрать - значение остаётся прежним (Вывод 2). Размер файла равен 2608 байт. Из-за чего такое может происходить?
   Видео: https://yadi.sk/i/MJ1FmIkDHowwLw
 
 Сообщение отредактировал kalumb - Понедельник, 16 Декабря 2019, 00:19  |  
| 
 | 
 |    | 
| drcrack | Дата: Воскресенье, 15 Декабря 2019, 17:57 | Сообщение # 2 |  
| 
 старожил 
Сейчас нет на сайте 
 
 | симптомы указывают на то, что: 1. размер буфера меньше чем нужно и внутри функции перезаписывается следующая за буфером переменная в памяти (BufferSize) 2. включена оптимизация из-за чего компилятор может менять инструкции местами итд исходя из своих представлений о быстром коде, это и приводит к странному поведению
 
 Сообщение отредактировал drcrack - Воскресенье, 15 Декабря 2019, 17:58  |  
| 
 | 
 |    | 
| Dymkens | Дата: Воскресенье, 15 Декабря 2019, 18:04 | Сообщение # 3 |  
 
почетный гость 
Сейчас нет на сайте 
 
 | Помочь вряд ли смогу, но все ровно назрело пару вопросов. Изменение значения переменной всегда одинаковое (268551192)? Будет ли значение увеличиваться при добавлении нескольких команд printf? И пробовали ли Вы использовать "cout" вместо "printf"?
  Моя первая игра - MilvusX
 |  
| 
 | 
 |    | 
| kalumb | Дата: Воскресенье, 15 Декабря 2019, 18:52 | Сообщение # 4 |  
| 
 почетный гость 
Сейчас нет на сайте 
 
 | Dymkens, я изменил первый вывод на это:
 Код printf("Size1 File %s = %d\n", Filename, BufferSize-5);  Первый вывод: 2603, дальше уже значение другое - 268551108. У меня ниже идут ещё выводы. На переменную там ничего не влияет, но значение изменяется дальше уже на 268551284. Сейчас и без 5 выводит 268551108 во втором выводе. Нет, количество функций printf не влияет на вывод. Код на Си, поэтому cout не пробовал. drcrack, я менял местами объявления переменных, результат тот же. Также я смотрел декомпозированный код в IDA, там всё нормально, все инструкции на своих местах.Добавлено (15 Декабря 2019, 19:27) --------------------------------------------- Помогло добавление ещё одной переменной.
  Код DWORD BufferSize1 = 0; ///////////////////////////// Buffer = callbacks.Dll_LoadFile(ExtData, Filename, &BufferSize1); BufferSize = BufferSize1  Но сейчас появились проблемы в других местах. В любом случае такое поведение очень странное.
 
 Сообщение отредактировал kalumb - Воскресенье, 15 Декабря 2019, 18:53  |  
| 
 | 
 |    | 
| drcrack | Дата: Воскресенье, 15 Декабря 2019, 19:51 | Сообщение # 5 |  
| 
 старожил 
Сейчас нет на сайте 
 
 | покажи лучше код Dll_LoadFile
 |  
| 
 | 
 |    | 
| kalumb | Дата: Воскресенье, 15 Декабря 2019, 21:29 | Сообщение # 6 |  
| 
 почетный гость 
Сейчас нет на сайте 
 
 | Вот видео с отладкой. Я убираю комментарий с вывода - и значение меняется. https://yadi.sk/i/MJ1FmIkDHowwLw
 
 Сообщение отредактировал kalumb - Суббота, 21 Декабря 2019, 02:12  |  
| 
 | 
 |    | 
| drcrack | Дата: Воскресенье, 15 Декабря 2019, 23:39 | Сообщение # 7 |  
| 
 старожил 
Сейчас нет на сайте 
 
 | попробуй вручную поставить размер буфера скажем в 10000000 и посмотри сохранится ли ошибка
 |  
| 
 | 
 |    | 
| kalumb | Дата: Понедельник, 16 Декабря 2019, 00:29 | Сообщение # 8 |  
| 
 почетный гость 
Сейчас нет на сайте 
 
 | drcrack, ошибка осталась. Вот другой видос из другого куска кода. Тут я вообще ничего не дописываю в исходник, но переменная всё равно меняет значение. https://yadi.sk/i/-aB4eX7629rkJA
 |  
| 
 | 
 |    | 
| Snake174 | Дата: Понедельник, 16 Декабря 2019, 06:41 | Сообщение # 9 |  
 
участник 
Сейчас нет на сайте 
 
 | Код  printf("Size1 File %s = %u\n", Filename, BufferSize); printf("Size1 File %s = %lu\n", Filename, BufferSize);
 
  
  Не следует обманывать инспектора   Pipmak Assistant   Love2D Exporter   Love2D-Helpers     Old Consoles Games
 
 Сообщение отредактировал Snake174 - Понедельник, 16 Декабря 2019, 08:54  |  
| 
 | 
 |    | 
| drcrack | Дата: Понедельник, 16 Декабря 2019, 07:49 | Сообщение # 10 |  
| 
 старожил 
Сейчас нет на сайте 
 
 | попробуй другой компилятор
 |  
| 
 | 
 |    | 
| kalumb | Дата: Понедельник, 16 Декабря 2019, 14:14 | Сообщение # 11 |  
| 
 почетный гость 
Сейчас нет на сайте 
 
 | Snake174, проблема не выводе, а в изменении переменной в памяти. Выключил оптимизацию в свойствах проекта, теперь проблемы с переменной len нет. Но первая проблема с выводом не исчезла. Я попробовал обернуть функцию вывода в свою - переменная поменяла значение на 150.
  Добавлено (16 Декабря 2019, 23:21) --------------------------------------------- Всё, с проблемой я разобрался. Такое поведение было вызвано несоответствием типов вызывающей программы и DLL. При этом я сам допустил ошибку: запускал отладку в релизной версии, из-за чего и не мог понять, что происходит, т.к. никаких предупреждений от компилятора я не получал. До этого я потратил много времени на компиляцию вызывающей программы, в Debug она так и не запускается (там нужно дописывать пути к заголовкам, что сделал только для релизной версии) :). Так вот при запуске отладчика в Debug режиме после работы функции, которая возвращала буфер, VS выдаёт предупреждение о проблемах с регистром ESP.
  В DLL у меня подключался заголовочный файл wintypes.h, в котором были описаны типы (что-то такое: typedef uint32_t DWORD;). А в вызывающей программе использовался стандартный windows.h, который я и прописал в коде библиотеки. Так что для решения проблемы достаточно было поменять одну строку.
  Я также определил, на какое значение изменялась моя переменная. В зависимости от кода значения будут разными. Если говорить о моём случае, когда значение менялось из-за вызова printf, то менялось оно на адрес команды после вызова функции (то есть на адрес команды после call). А значение переменной просто “затиралось” в стеке. Вместо printf я пробовал вызывать пустую функцию, которая ничего не возвращает, а на вход принимает int. Результат:
 
  Сейчас всё работает. Спасибо всем за помощь!
 
 Сообщение отредактировал kalumb - Вторник, 17 Декабря 2019, 12:06  |  
| 
 | 
 |    | 
| drcrack | Дата: Вторник, 17 Декабря 2019, 03:34 | Сообщение # 12 |  
| 
 старожил 
Сейчас нет на сайте 
 
 | кароче классический С++ круто наверно два дня разбираться с багом который прогрессивная часть человечества победила 20 лет назад с разработкой безопасных языков вроде джавы
 
 Сообщение отредактировал drcrack - Вторник, 17 Декабря 2019, 03:34  |  
| 
 | 
 |    | 
| kalumb | Дата: Вторник, 17 Декабря 2019, 12:49 | Сообщение # 13 |  
| 
 почетный гость 
Сейчас нет на сайте 
 
 | drcrack, ну я бы не назвал это багом. VS же выдаёт предупреждение. Из-за отсутствия опыта в отладке на решение проблемы ушло так много времени.
 |  
| 
 | 
 |    |