Почему меняется значение переменной? - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Пишу вот такой код:
Листинг программы
  1. #include <stdio.h>
  2. #include <sys/ioctl.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <linux/fb.h>
  7. #include <unistd.h>
  8. int main (void)
  9. {
  10. int *pi = NULL;
  11. int ID = open("/dev/fb0", O_RDWR|O_NONBLOCK);
  12. ioctl(ID, FBIOGET_VSCREENINFO, &pi);
  13. ioctl(ID, FBIOPUT_VSCREENINFO, &pi);
  14. ioctl(ID, 0x4040462e, 0xbe94eac0);
  15. ioctl(ID, 0x4004462f, 0xbe94ead8);
  16. return 0;
  17. }
Смотрю через strace, получаю такую картинку:
Листинг программы
  1. open("/dev/fb0", O_RDWR|O_NONBLOCK) = 4
  2. ioctl(4, FBIOGET_VSCREENINFO, 0xbec29d4c) = 0
  3. ioctl(600, FBIOPUT_VSCREENINFO, 0xbec29d4c) = -1 EBADF (Bad file descriptor)
  4. ioctl(600, 0x4040462e, 0xbe94eac0) = -1 EBADF (Bad file descriptor)
  5. ioctl(600, 0x4004462f, 0xbe94ead8) = -1 EBADF (Bad file descriptor)
  6. open("/dev/tty", O_RDWR|O_NOCTTY|O_NONBLOCK) = 5
  7. writev(5, [{"*** stack smashing detected ***:"..., 33}, {"./a.out", 7}, {" terminated\n", 12}], 3*** stack smashing detected *) = 29
Как значение ID перескакивает с 4 до 600? Что то намудрил с указателем, не могу понять, что именно.

Решение задачи: «Почему меняется значение переменной?»

textual
Листинг программы
  1. #include <stdio.h>
  2. // Read in header files
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <linux/fb.h>
  7. #include <unistd.h>
  8. #include <string.h>
  9. #include <sys/mman.h>
  10. #include <sys/ioctl.h>
  11.  
  12.  
  13. #define putpixel(_x, _y, _c) \
  14. if ((_x) & 01) {    \
  15. data[((_y)*width + (_x)) >> 1] &= 0xF0; \
  16. data[((_y)*width + (_x)) >> 1] |= (_c & 0x0F);  \
  17. } else {    \
  18. data[((_y)*width + (_x)) >> 1] &= 0x0F; \
  19. data[((_y)*width + (_x)) >> 1] |= ((_c & 0x0F) << 4);   \
  20. }
  21.  
  22. int main(int argc, char** argv) {
  23. int width = 0;
  24. int height = 0;
  25. int row, column, i, j;
  26.  
  27. // open framebuffer device and read out info
  28. int fd = open("/dev/fb0", O_RDWR);
  29.  
  30. struct fb_var_screeninfo screeninfo;
  31. ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo);
  32.  
  33. // determine size
  34. width = screeninfo.xres;
  35. height = screeninfo.yres;
  36.  
  37. printf("Size: %d x %d\n", width, height);
  38.  
  39. // embed framebuffer into memory
  40.  
  41. unsigned char *data = (unsigned char*)
  42. mmap(0, width * height / 2,
  43. PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  44.  
  45. // Clear memory (4 bpp)
  46. memset(data, 0, width * height / 2);
  47.  
  48. // Draw a box
  49. for (i = 100; i <= 200; ++i) {
  50. putpixel(300, i, 0xF);
  51. putpixel(400, i, 0xF);
  52. putpixel(i+200, 100, 0xF);
  53. putpixel(i+200, 200, 0xF);
  54. }
  55.  
  56. // mask framebuffer out of memory
  57. munmap(data, width * height / 2);
  58.  
  59. ioctl(3, 0x4040462e, 0);
  60. }

Объяснение кода листинга программы

  1. #include Включает в себя файл стандартного ввода/вывода, который необходим для работы с функциями вывода в консоль.
  2. #include <sys/types.h> Включает в себя файл типов системных вызовов, который содержит определения типов данных для системных вызовов.
  3. #include <sys/stat.h> Включает в себя файл статистики системных вызовов, который содержит определения для манипулирования файловой системой.
  4. #include Включает в себя файл открытий файлов, который содержит определения для манипулирования файлами.
  5. #include <linux/fb.h> Включает в себя заголовочный файл Linux Frame Buffer, который содержит определения для работы с фреймбуфером.
  6. #include Включает в себя файл системных вызовов, который содержит определения для низкоуровневых системных вызовов.
  7. #include Включает в себя файл строки, который содержит определения для манипулирования строками.
  8. #include <sys/mman.h> Включает в себя файл памяти MAP, который содержит определения для манипулирования памятью MAP.
  9. #include <sys/ioctl.h> Включает в себя файл управления вводом/выводом, который содержит определения для управления устройствами ввода/вывода.
  10. #define putpixel(_x, _y, _c) \ Это определение макроса putpixel, который будет использоваться в коде для установки пикселя на экране.
  11. if ((_x) & 01) {\ Это условие проверяет, является ли самый старший бит x равным 1.
  12. data[((_y)*width + (_x)) >> 1] &= 0xF0; Этот код обновляет значение указанного адреса в массиве data, сбрасывая нижние 4 бита.
  13. data[((_y)*width + (_x)) >> 1] |= (_c & 0x0F); Этот код обновляет значение указанного адреса в массиве data, устанавливая нижние 4 бита равными значению цвета.
  14. else {\ Это условие проверяет, является ли самый старший бит x равным 0.
  15. data[((_y)*width + (_x)) >> 1] &= 0x0F; Этот код обновляет значение указанного адреса в массиве data, устанавливая только нижние 4 бита.
  16. data[((_y)*width + (_x)) >> 1] |= ((_c & 0x0F) << 4); Этот код обновляет значение указанного адреса в массиве data, устанавливая верхние 4 бита равными значению цвета.
  17. int main(int argc, char** argv) {\ Это определение функции main, которая является точкой входа в программу.
  18. int width = 0; Эта переменная инициализирует ширину экрана.
  19. int height = 0; Эта переменная инициализирует высоту экрана.
  20. int row, column, i, j; Эти переменные используются для итерации по экрану при рисовании прямоугольника.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4.067 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы