1. C++ / Говнокод #27474

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    Game::Game()
    {
        run = true;//флаг признак нажатия кнопки выхода F5
        Matrix = new int* [8];//Поле 64 ячейки - значения 0 - для пустой ячейки, для игрока каждая пешка-шашка от 1 до 9, для компьютера значения в матрице от 10 до 18
        for (int i = 0; i < 8; i++)
            Matrix[i] = new int[8];
        //Квадраты координат нужны чтобы программа знала какие ячейки над указателем мыши, 64 квадрата
        QuadCoorXleft = new int* [8];//каждой ячейки матрицы Matrix соответстует квадрат координат для мыши xleft означает левую координату x
        QuadCoorXright = new int* [8];//xright - правая x
        QuadCoorYdown = new int* [8];//верхняя y координата
        QuadCoorYup = new int* [8];//нижняя y координата
        for (int i = 0; i < 8; i++)
        {
            QuadCoorXleft[i] = new int[8];
            QuadCoorXright[i] = new int[8];
            QuadCoorYdown[i] = new int[8];
            QuadCoorYup[i] = new int[8];
        }
        //Координаты пешек для отрисовки
        ChessX = new double[18];//X
        ChessY = new double[18];//Y
        //Выделяемая пешка ее координаты и значения
        ActiveX = -1;//X
        ActiveY = -1;//Y
        Active = -1;//Value
        firstplayer = true;//флаг того что можете игрок 1й ходить
        secondplayer = false;//флаг того что можете игрок 2й ходить
        ai = new bool[18];//ячейки флаги того что пешка на финишной позиции
        chessai tmp;
        for (int i = 0; i < 18; i++)
        {
            ai[i] = false;
            if (i > 8)
            {
                tmp.ai = ai[i];
                tmp.value = i+1;
                Ai.push_back(tmp);//Вектор с флагами финиша каждой пешки для искуственного интеллекта
            }
        }
        aicountfirstrow = 0;//счетчик кол-ва пешек ИИ(искуственного интеллекта) на верхней строчке(0-я)
        aicountsecondrow = 0;//счетчик кол-ва пешек ИИ на предверхней строчке(1-я)
        aicountthirdrow = 0;//счетчик кол-ва пешек ИИ на предпредверхней строчке(2-я)
    }

    https://github.com/Beginerok/DominiGames/blob/master/Domini/Chess/Chess/Game.cpp

    https://habr.com/ru/post/563398/
    Странные шахматы как тестовое задание

    Запостил: PolinaAksenova, 18 Июня 2021

    Комментарии (175) RSS

    • > Где-то более года назад мне пришлось делать одно тестовое задание чтобы устроится на работу. Выполнил я его в срок, но конкуренция была большая и скорее всего взяли человека который сделал его с помощью рекомендованных технологий и красочнее.
      (╥﹏╥)
      Ответить
      • void Game::Move_Up()
        {
        	//Ход игрока вверх
        	if (Active > 0 && ActiveX != 0 && Matrix[ActiveX-1][ActiveY] == 0)//Если выделенная пешка и не самая верхняя строчка и ячейка выше пустая
        	{
        		Matrix[ActiveX-1][ActiveY] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке выше текущюю(выделенную пешку)
        		Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую 
        		ChessY[Active-1] += 0.2;//перемещаем координату У пешки вверх для отрисовки
        		ActiveX = -1;//стираем координаты выделенной пешки
        		ActiveY = -1;//стираем координаты выделенной пешки
        		Active = -1;//делаем неактивной текущую выделенную фигуру
        		std::cout << " Player MoveUp " << Active << std::endl;
        		firstplayer = false;
        		secondplayer = true;//меняем флаги хода от игрока к ИИ
        	}
        }
        void Game::Move_Down()
        {
        	//Ход игрока вниз
        	if (Active > 0 && ActiveX != 7 && Matrix[ActiveX+1][ActiveY] == 0)//Если выделенная пешка и не самая нижняя строчка и ячейка ниже пустая
        	{
        		Matrix[ActiveX+1][ActiveY] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке ниже текущюю(выделенную пешку)
        		Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую 
        		ChessY[Active-1] -= 0.2;//перемещаем координату У пешки вниз для отрисовки
        		ActiveX = -1;//стираем координаты выделенной пешки
        		ActiveY = -1;//стираем координаты выделенной пешки
        		Active = -1;//делаем неактивной текущую выделенную фигуру
        		std::cout << "Player MoveDown " << Active << std::endl;
        		firstplayer = false;
        		secondplayer = true;//меняем флаги хода от игрока к ИИ
        	}
        }
        Ответить
        • void Game::Move_Right()
          {
          	//Ход игрока вправо
          	if (Active > 0 && ActiveY != 7 && Matrix[ActiveX][ActiveY+1] == 0)//Если выделенная пешка и не самая правая строчка и ячейка справа пустая
          	{
          		Matrix[ActiveX][ActiveY+1] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке справа текущюю(выделенную пешку)
          		Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую 
          		ChessX[Active-1] += 0.2;//перемещаем координату Х пешки вправо для отрисовки
          		ActiveX = -1;//стираем координаты выделенной пешки
          		ActiveY = -1;//стираем координаты выделенной пешки
          		Active = -1;//делаем неактивной текущую выделенную фигуру
          		std::cout << "MoveRight " << Active << std::endl;
          		firstplayer = false;
          		secondplayer = true;//меняем флаги хода от игрока к ИИ
          	}
          }
          void Game::Move_Left()
          {
          	//Ход игрока влево 
          	if (Active > 0 && ActiveY != 0 && Matrix[ActiveX][ActiveY-1] == 0)//Если выделенная пешка и не самая левая строчка и ячейка слева пустая
          	{
          		Matrix[ActiveX][ActiveY-1] = Matrix[ActiveX][ActiveY] ;//присваиваем ячейке слева текущюю(выделенную пешку)
          		Matrix[ActiveX][ActiveY] = 0;//затираем старую ячейку на пустую 
          		ChessX[Active-1] -= 0.2;//перемещаем координату Х пешки влево для отрисовки
          		ActiveX = -1;//стираем координаты выделенной пешки
          		ActiveY = -1;//стираем координаты выделенной пешки
          		Active = -1;//делаем неактивной текущую выделенную фигуру
          		std::cout << "MoveLeft " << Active << std::endl;
          		firstplayer = false;
          		secondplayer = true;//меняем флаги хода от игрока к ИИ
          	}
          }


          Это надо было одной функцией оформить?
          Ответить
          • >0.2
            >-1
            какой ИИ ))
            Ответить
            • Надеюсь, он эти координаты хоть не сравнивает. А то потом получится, что две пешки на одной клетке рисуются, а ChessX[Passive-1] != ChessX[Active-1]. // 0.200000000001
              Ответить
      • https://habr.com/ru/post/563398/#comment_23164342
        Ответить
    • А какой там ещё есть прожект!

      https://gist.github.com/ForNeVeR/9001938

      Щи!!!! Симулятор жестокости.
      Ответить
    • «Вашим следующим шагом должно быть либо удаление этой статьи, либо вторая часть: работа над ошибками. В ней Вы должны рассказать нам (а не мы Вам), почему Вас не взяли и как Вы исправили бы свой код, чтобы стать лучше»

      Главное отличие хабра от говнокода. Не в пользу хабра.
      Ответить
      • Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
        Ответить
    • >> Game::Game()
      какое имя метода ))

      >> Matrix = new int* [8]
      >> Matrix[i] = new int[8];
      какая структура ))


      > //Координаты пешек для отрисовки
      >> ChessX = new double[18];
      надеюсь, для каждой фигуры есть такой массив?

      >>double
      пешка может на пол шышечки на клеточку залезть?

      >>if (i > 8)
      я понял, это потому что 8x8?

      >aicountthirdrow
      а есть eighthrow?
      Ответить
      • > if (i > 8)

        Это потому что в бильярде есть такой шар.
        Ответить
      • > какое имя метода ))

        Эм, конструктор же. Что не так?
        Ответить
    • Автор еще интересную статью написал
      https://habr.com/ru/post/541462/

      Рассмотрим 5 сортировок. Это пузырьковая(bubble), шейкерная(shake), пирамидальная(heap), вставками(insertion) и быстрая(quick).

      Для анализа их скорости будет использоваться функция clock()

      Каковы же результаты?

      С большим отрывом идет sort из stl, потом вставками, пирамидальная, шейкерная и заканчивает пузырьковая.

      -----

      и как всегда в таких штуках меня поражает, что автору совсем не 16 лет, как вы бы могли подумать
      Ответить
      • Ну и как бы ты их соревновал?)

        Кстати, в почему сорт из СТЛ такой быстрый?
        Ответить
        • тут и табличка есть
          https://www.geeksforgeeks.org/analysis-of-different-sorting-techniques/

          Если уж реально измерять скорость, то на реальных данных

          >быстрый
          не знаю, наверное его писали скильные питухи, знающие как работает процесарь
          Ответить
      • и еще одну... причем сразу про source nat и про mysql_real_connect и про ООП
        https://habr.com/ru/post/461503/
        можно еще про vectordrum пошутить, но я не буду
        Ответить
        • В общем, для своего приложения я выбрал mysql и посмотрел что есть на Linux. Там уже был установлен он, но пароль никто не знает, а те кто знали забыли (те кто работал до меня). Узнав что он никому не нужен, я его удалил и попытался установить заново. Память не хватало и поскольку чтобы исправить эту ошибку пришлось бы подключать к нему монитор и клавиатуру с мышью, я решил бросить это дело
          Ответить
          • Какой анскилл )))
            Ответить
          • > поскольку чтобы исправить эту ошибку пришлось бы подключать к нему монитор и клавиатуру с мышью, я решил бросить это дело

            КАКОЙ ЛИНУКС !!! ))))))
            Ответить
          • > я его удалил и попытался установить заново
            Мартышка и очки Вендоадмин и линукс
            Ответить
            • ну а что делать, когда в линуксе нет "sfc /scannow" (в солярке есть pkg verify, лол)
              Ответить
      • да это дед 92 года, из ника понятно
        Ответить
    • А вот тут
      https://habr.com/ru/post/520400/
      автор показывает, что бывает, если накопипастить разные строчки с разных мест часть на си, часть на плюсах)

      newsockfd = new int[maxclients];
      thread = (HANDLE*)malloc(sizeof(HANDLE) * maxclients);
      args = new struct arg_sa[maxclients];
      ///
      unsigned long long id;
      std::vector<uint64_t>* plaintext = new std::vector<uint64_t>();
      ///
      #define ROL(x,n,xsize)((x<<n)|(x>>(xsize-n)))
      #define RKEY(r)((ROR(K,r*3,size64*8))&F32)
      const uint64_t K = 0x96EA704CFB1CF671;//ключ шифрования


      там еще много прекрасного, вроде такго
      >Вкратце в вечном цикле создаются потоки для каждого клиента и ждут accept

      сама задача такая: автор не знал, что в активном режиме FTP не работает за NATом, и "Не найдя ответа на куче форумов" решил написать свой сервер и клиент на винсок, а за одно и реализовать шифрование (про TLS автор не знает)
      Ответить
      • > = new std::vector<uint64_t>();
        Повеяло корпоративным духом джавамэня.
        (ノ´ヮ`)ノ*: ・゚
        Ответить
        • для полноты картины нужно хранить в векторе указатели на int

          ну хотя да: автор думает, что векторы всегда нужно создавать через new.

          вообще по какому приниципу он выбирает место для хранения не очень понятно. Кажется, что если код напоминает ему C++, то он делает new, а иначе автоматическую (или статическую) перерменную
          Ответить
          • Ну стэк вообще-то не бесконечный, чтобы на нём вектора хранить.
            Ответить
            • Ну стэк вообще-то не бесконечный, чтобы на нём указатели на вектора хранить:)

              Если без зеленого, то вектор же хранит свои данные в алокаторе (вероятнее всего в куче), а на стеке там только такая куржопенькая ручка из трёх указателей (или двух указателей и размера?) (потому вектор обычно sizeof 24, но не обязан)
              Ответить
              • Ну тогда ладно, я спокоен. А никак нельзя вектор на куче выделить? Это багор, ведь код с вектором уже нельзя перенести на юмбеддед платформу.
                Ответить
                • можно, например автор так и сделал) только зачем? чтобы была лишняя косвенность?

                  алсо, если уж выделять его там, то хотябы не через сырой ню, а через умный указатель, чтобы он сам удалился (у автора он не)

                  Про юбмедед не понял. У тебя там скорее всего заранее известно сколько памяти нужно, и можно взять вообще массив
                  Ответить
                  • Ой, я оговорился: не на куче, а на стеке. Конечно же, трудностей в выделении вектора (вернее, его элементов) в куче нет. Но если это дефолтный способ занять память, то в эмбеддеде его уже не используешь. Наверное, j123123 поэтому ненавидит «С++».

                    Кстати, а как тебе языки с возможностью шаманить с аллокаторами? Типа «Odin».
                    Ответить
                    • > Кстати, а как тебе языки с возможностью шаманить с аллокаторами?
                      Типа "C++"?
                      Ответить
                    • а ты уверен, что тебе нужен std::vector - контейнер, который способен динамически менять свой размер при жизни, который аллоцирует обычно с запасом, т.к. позволяет вставлять новые элементы в т.ч. в середину - а не std::array?
                      j123123 ненавидит С++, потому что не смог, вот и бесится
                      Ответить
                      • std::vector и std::array это как Chad и Virgin, так что я за std::vector.

                        Кстати, смотри какой аллокатор:
                        #include <memory>
                        #include <stdio.h>
                        
                        namespace mmap_allocator_namespace
                        {
                                // See StackOverflow replies to this answer for important commentary about inheriting from std::allocator before replicating this code.
                                template <typename T>
                                class mmap_allocator: public std::allocator<T>
                                {
                        public:
                                        typedef size_t size_type;
                                        typedef T* pointer;
                                        typedef const T* const_pointer;
                        
                                        template<typename _Tp1>
                                        struct rebind
                                        {
                                                typedef mmap_allocator<_Tp1> other;
                                        };
                        
                                        pointer allocate(size_type n, const void *hint=0)
                                        {
                                                fprintf(stderr, "Alloc %d bytes.\n", n*sizeof(T));
                                                return std::allocator<T>::allocate(n, hint);
                                        }
                        
                                        void deallocate(pointer p, size_type n)
                                        {
                                                fprintf(stderr, "Dealloc %d bytes (%p).\n", n*sizeof(T), p);
                                                return std::allocator<T>::deallocate(p, n);
                                        }
                        
                                        mmap_allocator() throw(): std::allocator<T>() { fprintf(stderr, "Hello allocator!\n"); }
                                        mmap_allocator(const mmap_allocator &a) throw(): std::allocator<T>(a) { }
                                        template <class U>                    
                                        mmap_allocator(const mmap_allocator<U> &a) throw(): std::allocator<T>(a) { }
                                        ~mmap_allocator() throw() { }
                                };
                        }
                        Ответить
                        • какой? называется mmap, а делает-то что?
                          Ответить
                          • Основное написали, осталось просто добавить mmap().
                            Ответить
                          • Я не знаю, я его скопировал из интернета, чтобы вам показать.

                            Вроде бы, аллоцирует всякую фигню в ФАЙЛЕ, который находится в ОПЕРАТИВНОЙ ПАМЯТИ.
                            Ответить
                            • пока что он только срёт в stderr хелоу ворлдами, а всю работу делает std::allocator
                              Ответить
                              • То есть это плохой пример аллокатора, на который лучше не равняться?
                                Ответить
                                • Да. Рав-ня-йся лучше ня этот:
                                  #include <memory>
                                  #include <stdio.h>
                                  
                                  namespace logging_allocator_namespace
                                  {
                                          // See StackOverflow replies to this answer for important commentary about inheriting from std::allocator before replicating this code.
                                          template <typename T>
                                          class logging_allocator: public std::allocator<T>
                                          {
                                  public:
                                                  typedef size_t size_type;
                                                  typedef T* pointer;
                                                  typedef const T* const_pointer;
                                  
                                                  template<typename _Tp1>
                                                  struct rebind
                                                  {
                                                          typedef logging_allocator<_Tp1> other;
                                                  };
                                  
                                                  pointer allocate(size_type n, const void *hint=0)
                                                  {
                                                          fprintf(stderr, "Alloc %d bytes.\n", n*sizeof(T));
                                                          return std::allocator<T>::allocate(n, hint);
                                                  }
                                  
                                                  void deallocate(pointer p, size_type n)
                                                  {
                                                          fprintf(stderr, "Dealloc %d bytes (%p).\n", n*sizeof(T), p);
                                                          return std::allocator<T>::deallocate(p, n);
                                                  }
                                  
                                                  logging_allocator() throw(): std::allocator<T>() { fprintf(stderr, "Hello allocator!\n"); }
                                                  logging_allocator(const logging_allocator &a) throw(): std::allocator<T>(a) { }
                                                  template <class U>                    
                                                  logging_allocator(const logging_allocator<U> &a) throw(): std::allocator<T>(a) { }
                                                  ~logging_allocator() throw() { }
                                          };
                                  }
                                  Ответить
                    • ну ты можешь сделать свой аллокатор, и пытаться срать в стек

                      вот такая хернь есть

                      https://chromium.googlesource.com/chromium/chromium/+/refs/heads/main/base/stack_container.h

                      // This allocator can be used with STL containers to provide a stack buffer
                      // from which to allocate memory

                      Есть еще VLA, но вроде тока в няшной.

                      наконец, если ты статически знаешь размер, то есть std::array
                      ----

                      Вообще если ты заранее знаешь размер (в ембеде вероятно это так) то может и вектор тебе не нужен
                      Ответить
                      • Я до этого дня даже не подозревал, что в «С++» есть какие-то «аллокаторы»...
                        Ответить
                        • https://www.youtube.com/watch?v=VolXYNyQJAM
                          Ответить
                        • Степанов (или кто там делал STL) прекрасно знал, какие сишники байтоебы, и понимал, что если не дать им возможность контролировать выделение памяти для контейнеов, то они ими ни в жизни пользоваться не будут, а навелосипедят рядом свое, потому что "а зачем мне лишний brk"
                          Ответить
                          • Почему же этот Степанов не сделал в своих конь-тейнерах фунцкию realloc()?
                            Ответить
                            • В смысле не сделал? Этим аллокатор занимается, когда его просят.
                              Вектор даёт крутилку предусмотреть нужный тебе размер аллокации заблаговременно

                              https://en.cppreference.com/w/cpp/container/vector/reserve
                              Ответить
                              • Рассмотрим такой код
                                #include <stdio.h>
                                #include <stdlib.h>
                                #include <iostream>
                                #include <vector>
                                
                                
                                int main ()
                                {
                                  
                                  std::vector<int> myvector;
                                
                                  for (int i = 0; i <= 9999999; i++ )
                                  {
                                    myvector.push_back (i);
                                  }
                                  return 0;
                                }


                                Скомпилируем и запустим под strace:
                                ...
                                mmap(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6dd1e9c000
                                brk(0x561f9bed0000)                     = 0x561f9bed0000
                                mmap(NULL, 266240, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6dd1e5b000
                                munmap(0x7f6dd1e9c000, 135168)          = 0
                                mmap(NULL, 528384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6dd1dda000
                                munmap(0x7f6dd1e5b000, 266240)          = 0
                                mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6dd1cd9000
                                munmap(0x7f6dd1dda000, 528384)          = 0
                                mmap(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6dd1ad8000
                                munmap(0x7f6dd1cd9000, 1052672)         = 0
                                mmap(NULL, 4198400, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6dd16d7000


                                Почему я не вижу тут mremap() ?
                                Ответить
                                • Почему плюсы анмапят, и мапят заново -- я не знаю


                                  но тока он mremap не использует, а не "realloc"


                                  realloc тоже не обязан ремапить, если
                                  он может рядышком выделить память

                                  #include <stdlib.h>
                                  
                                  void main() {
                                  	const size_t limit = 4;
                                  	char* foo = malloc(4096);
                                  	for(size_t i = 4096; i < 4096 * limit; i++) {
                                  		foo = realloc(foo, i);
                                  	}
                                  }

                                  realloc есть, а ремапа нет (у меня)

                                  а если ``limit`` поменять на ``4096``, то появится


                                  зы: во
                                  https://news.ycombinator.com/item?id=23677695
                                  Ответить
                              • А если сделать какую-то такую херню с realloc()
                                #include <stdlib.h>
                                #include <unistd.h>
                                #include <errno.h>
                                
                                typedef struct
                                {
                                  size_t size;
                                  size_t position;
                                  int arrm[1];
                                } myarr;
                                
                                void arr_check_and_push(myarr **arr, int *a)
                                {
                                
                                  
                                  if ( (*arr)->size <= (*arr)->position)
                                  {
                                    (*arr)->size <<= 1;
                                    //fprintf (stderr ,"realloc(%p, %zu)",*arr,(*arr)->size * sizeof(int) + sizeof(size_t) * 2);
                                    *arr = (myarr *)realloc(*arr, (*arr)->size * sizeof(int) + sizeof(size_t) * 2);
                                    if ((void *)*arr == NULL)
                                      exit(ENOMEM);
                                  }
                                  (*arr)->arrm[(*arr)->position++] = *a;
                                }
                                
                                int main ()
                                {
                                
                                  myarr *arr = (myarr*)malloc(sizeof(size_t)*2+sizeof(int));
                                  arr->size = 1;
                                  arr->position = 0;
                                  arr->arrm[0] = 0;
                                
                                  for (int i = 0; i <= 9999999; i++ )
                                    arr_check_and_push(&arr, &i);
                                    
                                  free(arr);
                                  return 0;
                                }


                                И посмотреть на strace
                                mremap(0x7f6237a7a000, 266240, 528384, MREMAP_MAYMOVE) = 0x7f62379f9000
                                mremap(0x7f62379f9000, 528384, 1052672, MREMAP_MAYMOVE) = 0x7f62378f8000
                                mremap(0x7f62378f8000, 1052672, 2101248, MREMAP_MAYMOVE) = 0x7f62376f7000
                                mremap(0x7f62376f7000, 2101248, 4198400, MREMAP_MAYMOVE) = 0x7f62372f6000
                                mremap(0x7f62372f6000, 4198400, 8392704, MREMAP_MAYMOVE) = 0x7f6236af5000
                                mremap(0x7f6236af5000, 8392704, 16781312, MREMAP_MAYMOVE) = 0x7f6235af4000


                                Почему в контейнерах так не осилили сделать?
                                Ответить
                                • Не в контейнерах, а в аллокаторах не осилили.

                                  Комитет сказал нахуй надо. Слава демократии.
                                  https://stackoverflow.com/a/6391202
                                  Ответить
                            • Потому что realloc() — это образцово-показательный пример говна, образовавшегося из-за нярушения SRP.
                              Вызов realloc(), в силу своей говённости, ня позволяет детерминированно контролировать, будет ли диапазон памяти просто расширен или скопирован в новую область. Это, в свою очередь, ня позволило добавить универсальную функцию realloc() в аллокаторы, и как следствие — распространённые реализации контейнеров ня используют realloc().
                              Ответить
                              • Кстати, очень удивлён был, что нет функции вроде max_expand_size, которая бы вернула максимальный размер до которого realloc расширяется на месте. Заткнуло бы большинство проблем.
                                Ответить
                              • > Вызов realloc(), в силу своей говённости, ня позволяет детерминированно контролировать, будет ли диапазон памяти просто расширен или скопирован в новую область.

                                А в чем проблема? Для этого достаточно сравнивать указатель до и после realloc.

                                Если вместо malloc() делать new() - копирования хуйни - delete(), мы разве лучше что-то контролируем?
                                Ответить
                                • В том, что таким способом о копировании ты узнаешь после, собственно, копирования. А в общем случае копировать объекты через memcpy(), как делает это говноrealloc(), няльзя.
                                  Ответить
                                  • > В том, что таким способом о копировании ты узнаешь после, собственно, копирования.

                                    Почему меня это должно волновать? Вот конкретно для кейса, когда я делаю push_back в вектор, какая мне разница, откопируется ли оно при realloc или останется на месте? Я уж не говорю о том, что никакого фактического копирования может и не происходить, учитывая что есть MMU

                                    Каким образом вариант "всегда выделяем новую память и копируем хуйню из старой в новую, а старую освобождаем" оказывается лучше?
                                    Ответить
                                    • > Почему меня это должно волновать?
                                      Тебя-то понятное дело не должно, ты на крестах ня пишешь.

                                      В общем случае копировать объекты через memcpy(), как делает это говноrealloc(), няльзя.
                                      Ответить
                                      • > В общем случае копировать объекты через memcpy(), как делает это говноrealloc(), няльзя.

                                        Почему тогда для частных случаев нельзя использовать realloc() ?
                                        Ответить
                                        • Потому что слишком много работы (как для стандартизаторов, так и для авторов стандартных либ/компиляторов) ради минимального прироста производительности в редких случаях, который ещё и в някоторых случаях приведёт к деградации (когда система ня поддерживает быстрый realloc, няпример).
                                          Ответить
                                          • зато можно сэкономить на копировании говна же, а для С++ это может быть важно


                                            почему нету ключика "prefer_realloc" и разрешать тока для тривиали копибл?
                                            Ответить
                                      • Кстати да, вполне можно сделать и особый вариант realloc(), например realloc_if_ptr_will_be_same() который бы успешно расширял память, если это возможно при неизменении указателя (т.е. если можно довыделить страниц сзади), но который бы нихуя не делал при невозможности такого расширения. Такой вариант realloc-а крестовики бы стали запихивать в свои аллокаторы?
                                        Ответить
                                        • Да, стали бы (примерня такой пропозал и есть по ссылке дяди Ди выше). Но проблема остаётся той же: это нужня только для няскольких редких кейсов, это сложня реализовывать, это приведёт к деградации (лишние рантайм-проверки) для случаев, когда довыделять страниц няльзя.

                                          Собственно, если в твоём приложении реаллоцирование вектора с тривиальня-копируемыми объектами является бутылочным горлышком, то всегда можня взять другую либу, няпример, https://github.com/facebook/folly/blob/master/folly/docs/FBVector.md . Стандартные контейнеры — ня червонцы, всем и во всех случаях нрявиться не могут.
                                          Ответить
                                      • By default, if there is not sufficient space to expand a mapping
                                        at its current location, then mremap() fails


                                        Почему нельзя было сделть так:

                                        * Если можем расти на том же месте, то растем без копирования
                                        * Если не можем, и тривили копибл, то запускаемся с MREMAP_MAYMOVE

                                        А иначе делаем как сейчас


                                        Или это было бы не кросс-платформенно?
                                        Ответить
                                        • > Или это было бы не кросс-платформенно?

                                          Надо разобраться с тем, как эта херня с лоу-левельным выделением памяти работает например в той же винде. Наверняка можно что-то скостылить.
                                          Ответить
                                          • Ня винде анялогов mremap() нят. Там realloc() можня сделать только ручным юзермодным костылянием, что, конячно, по эффективности будет у GNU/Linux отсасывать.
                                            Ответить
                                            • > отсасывать

                                              От вас, Полина, не ожидал таких выражений
                                              Ответить
                                            • есть HeapReAlloc же, но это если ня мапить файл: виртпамять иначе на пинде работает
                                              Ответить
                                              • подведем итог:

                                                Реаллочить кококококтейнеры в общем случае нельзя, потому что в крестах (в отличие от няшки) бывают не тривиальные объекты, которые нельзя скокококококпировать просто так

                                                Можно было изъябнуца и сделать ооооптимизации, но всем опхуй
                                                Ответить
                                              • HeapCreate/HeapAlloc/HeapReAlloc — это и есть "можня сделать только ручным юзермодным костылянием". Эти функции работают поверх выделенного через VirtualAlloc блока, организуя в нём кучу исключительня юзермодными операциями, без помощи ядра/процессора.
                                                Ответить
                                                • Это верня: хипы это абстракции поверх VirtualAllocкнутой хуиты

                                                  Интересно было бы няписать статью со сравнением работы виртуальной памяти прыщей и винды, и вообще серию статей со сравнением подсистем (tty vs ConsoleAPI итд)

                                                  Я бы почитал
                                                  Ответить
                        • Аллокаторы в С++ несколько неудобны. У них есть параметр — тип объекта, поэтому, казалось бы, ты можешь оптимизировать своё говно под конкретный тип и хранить только его? Но хуй! Твой аллокатор должен поддерживать произвольные типы, потому что половина сущностей в стандартной библиотеке хранит ни хера ни T, а какой-нибудь _No__de<T> ([forward_]list, [multi]set/map, shared_ptr...). В общем, я за кастомный memory_resource с доступом через polymorphic_allocator.
                          Ответить
                          • > потому что половина сущностей в стандартной библиотеке хранит ни хера ни T, а какой-нибудь _No__de<T>
                            А как иняче-то сделать неинтрузивные list, set/map, shared_ptr? Тебе в любом случае придётся выделять "struct Node {Node *next; T value; }" для списка, "struct Node {Node *left, *right; T value; }" для сета/мапы и так далее.
                            Ответить
    • Некоторые вещи, которые есть в этом коде, нельзя писать даже в прототипе. Их вообще нигде нельзя писать, их нельзя ничем оправдать — не существует случая, когда они хороши.

      Никогда не говори никогда...
      Ответить
      • приведи реальный пример когда нужно писать
        Matrix[i] = new int[8];
            //Квадраты координат нужны чтобы программа знала какие ячейки над указателем мыши, 64 квадрата
            QuadCoorXleft = new int* [8];//каждой ячейки матрицы Matrix соответстует квадрат координат для мыши xleft означает левую координату x
            QuadCoorXright = new int* [8];//xright - правая x
            QuadCoorYdown = new int* [8];//верхняя y координата
            QuadCoorYup = new int* [8];//нижняя y координата
        Ответить
        • Ну для какой-нибудь разрежённой структуры, где в половине этих ячеек null'ы.

          У меня одно время было желание восемь звёзд ебануть. Пришлось его пересиливать и заворачивать в шоблон.
          Ответить
          • и чем нул в ячейке лучше ноля в массиве интов?

            Если же речь о том, что целый ряд "Xleft" можно не создавать?
            Тогда всё таки лучше завернуть это в объект и нормально чистить за собой
            Ответить
            • > что целый ряд можно не создавать

              Ну да, я поэтому и пишу про разрежённую структуру... Яркий пример -- интеловские пейджтейблы.

              > завернуть это в объект

              Да, но внутри то у него эти new никуда не денутся. А вектор-из-указателей для этого юзать особого смысла нет.
              Ответить
              • А что бы ты сделал, если у тебя в ряду есть N и N+90000, а остальное ноли? Сделал бы связспиок с указанием сколько нолей до следующего элемента?
                Иными словами как пропустить ряды я понял, а как бы ты пропустил колонку?

                >Да, но внутри то у него эти new никуда не денутся.
                хотябы снаружи не выглядело бы как грязь
                foo.createRow(9000)
                foo[1] = 200;
                Ответить
                • > если у тебя в ряду есть N и N+90000, а остальное ноли

                  Х.з., от плотности зависит... Хешмапу какую-нибудь, если плотность никакая. Если поплотнее -- N'арное дерево (те самые восемь звёзд).
                  Ответить
                  • То есть решение автора подходит только если у тебя много много пустых рядов (причем еще нужно где-то хранить расстояния между ними)
                    Ответить
                    • > решение автора

                      Мне лень вникать в эту портянку, сорри. Что за расстояния там хранятся?
                      Ответить
                      • всё же написино!
                        Matrix[i] = new int[8];
                            //Квадраты координат нужны чтобы программа знала какие ячейки над указателем мыши, 64 квадрата
                            QuadCoorXleft = new int* [8];//каждой ячейки матрицы Matrix соответстует квадрат координат для мыши xleft означает левую координату x
                            QuadCoorXright = new int* [8];//xright - правая x
                            QuadCoorYdown = new int* [8];//верхняя y координата
                            QuadCoorYup = new int* [8];//нижняя y координата


                        В общем тут вполне себе известный заранее, не разреженный и не очень большой массив какого-то говна, который не понятно зачем так сделан
                        Ответить
                • > как пропустить ряды я понял, а как бы ты пропустил колонку

                  Нужно больше индирекций! На первом слое пусть будут условно блоки по 10000 строк и 10000 колонок. На втором -- внутри них блоки по 100. На третьем -- собственно сами значения.

                  2D дерево, короче.
                  Ответить
                  • ну да, точно как таблицы страниц:)

                    сразу видно, что ты системщик ))
                    Ответить
                    • > точно как таблицы страниц

                      Я эту структуру хотела юзать чтобы карту для ММОРПГ хранить (зоны вокруг игроков префетчятся в память, остальные уходят спать на диск). Поэтому она действительно очень близка к пейджтейблам.

                      Обычный mmap тут не совсем подходил т.к. там куча вещей переменной длины и нужно было freeze/thaw обрабатывать явно.
                      Ответить
                      • звучит так, словно ты руками решил сделать работу за диспетчера виртуальной памяти

                        Нельзя было никак сделать свое "хранилище" из блоков размером в страницу, и как-то всё это туда упаковывать (ну переменной длинны, но можно же как-то всунуть?), чтобы он поднимал с диска страницы (и свопил их обратно)?
                        Ответить
                        • С mmap'ом консистентность данных поддерживать сложно... Он же вообще неуправляемый. Всё равно придётся какие-то журналы прикручивать и т.п.
                          Ответить
                          • а ты хотел сохранять состояние игры и переживать перезапуск типа?
                            тогда понятно

                            но всё равно выглядит как оверлеи прямо какие-то, хотя я верю, что гейдевки вполне могут и так
                            Ответить
                            • > сохранять состояние игры и переживать перезапуск

                              Охуенная будет ММО, если состояние не сохранять. Там ради этого второй процесс был, который в BDB изменения коммитил. На случай если основной наебнётся.

                              > гейдевки вполне могут и так

                              Да я сварщица не настоящая. Вангую, что в реале совсем другие архитектуры юзают. Здесь же даже масштабирование не было продумано.
                              Ответить
                              • По идее можно заммапленый мир переодически снепшотить как-то.. но правда не понятно как сделать консистентность не поставив всех раком
                                Ответить
                                • > снепшотить как-то

                                  Ну можно классику -- бекап + лог транзакций от бекапа. Работать будет.
                                  Ответить
                                • События в WAL (Write Ahead Log) дампить, и при рестарте проигрывать. Снапшотить асинхронно и как угодно, хоть грязными чтениями. По теореме Снаута главное чтобы WAL начинался с момента раньше первого грязного чтения.
                                  Ответить
                                  • Сначала писать в WAL, потом его проигрывать в mmapнутую память? Это годно, но нужно выбрать атомарность, если там каждый питушиный шажок это отдельная транзаккция, то будет неуободно

                                    вероятно можно делать транзакции по времени
                                    Ответить
                                    • > вероятно можно делать транзакции по времени

                                      Ну да, у меня каждый питушиный шажок отправлялся в соседний процесс на сохранение. А он каждую секунду коммитил пачками в BDB.

                                      Не обязательно же WAL флашить на каждый чих, если какие-то потери допустимы (секунда если процесс с базой помрёт, в районе одного кадра если основной).
                                      Ответить
                                    • > Сначала писать в WAL, потом его проигрывать в mmapнутую память? Это годно, но нужно выбрать атомарность, если там каждый питушиный шажок это отдельная транзаккция, то будет неуободно

                                      В няивной имплементации достаточно просто синхронизировать импорт операций из лога с чтениями, которые делает дампер снэпшотов, чтобы он мусор не прочитал. Транзакции не нужны по сути.
                                      Ответить
                                    • Обеспечивать высокий уровень нядёжности имеет смысл только для критических данных:
                                      \begin{enumerate}
                                      \item Различные балансы, как внутриигровых валют, так и донатных.
                                      \item Внутриигровые/донатные сделки (аукцион, магазины), письма.
                                      \item Характеристики персонажей (опыт, скиллы, достижения...).
                                      \item Инвентари персонажей, "банки"/"хранилища" и прочее.
                                      \item Характеристики предметов: кулдауны, прочности и так далее.
                                      \end{enumerate}
                                      Все эти данные желательня при падении процесса ня терять. Остальную же фигню, вроде положения ня карте, направления взгляда, скорости и прочего, можно хранить без особых церемоний: всё равно после аварийняго завершения процесса придётся всех персонажей телепортировать в безопасное место (стартовую локацию какую-нябудь).
                                      Ответить
                                      • > фигню, вроде положения ня карте, направления взгляда, скорости и прочего

                                        - спидраннеры оценят

                                        хотя какие конечно в мморпг спидраннеры
                                        Ответить
                                        • > спидраннеры оценят

                                          Блин, да в большинстве синглов чуть ли не всю карту резетят когда с чекпоинта перезагружаешься...

                                          З.Ы. Скучно стало, раньше можно было засейвиться за секунду до смерти и пытаться выбраться из этой ситуации.
                                          Ответить
                                          • ну да

                                            потому можно например прыгнуть с 100000 метров вниз, перед самым приземлением квиксейв-квиклоад и вуаля!
                                            Ответить
                                          • > с чекпоинта

                                            - FUUUU консольщина
                                            Ответить
                                            • консольщина это когда ты в Contra на денди все три жизни потратил, и заново проходи всё с начала

                                              На девятьсот девяносто шестой раз научишься первый уровень проходить
                                              Ответить
                                              • хуйня полная, не понимаю, почему до сих пор многие на это дрочат
                                                Ответить
                                                • Правильня, эти стрелялки такая глупость! "Клуб Романтики: Секрет небес" мне больше нравится ☆*:.。.o(≧▽≦)o.。.:*☆.
                                                  Ответить
                                                • > дрочат

                                                  потому что детство...
                                                  Ответить
                                              • > и заново проходи всё с начала

                                                Это олдскульная соснольщина. А в современной можно просто перекатиться за соседний ящик и смотреть кинцо в 30 FPS дальше.
                                                Ответить
                                                • В олдскульной тоже можно смотреть пока твой одноклассник играет:)

                                                  впрочем, в моих любимых играх можно было сохраняться в некоторых местах (в домах, например)
                                                  Ответить
                                                • нахрюк!

                                                  можно поставить самый высокий уровень сложности в современной соснольщине и получать два чекпоинта на уровень и ваншоты-хедшоты от любого ашота
                                                  Ответить
                                          • борманд, а ты играл в ждалкер?
                                            Ответить
                                        • Речь идёт об обеспечении нядёжности хранения ня случай падения процесса игры. После падения сервера спидраннерам будет нямножко няплевать, сохранилось ли их положение ня карте или нят.
                                          Ответить
                                          • "А теперь мы сдаём квест. Обычно после этого нас телепортируют из инстанса, и необходимо проходить квестовую линейку на 2-3 часа, чтобы попасть в него снова и завершить необходимый нам квест. Но если уронить сервер специально сформированным запросом до начала диалога в следующей локации, после перезапуска мы останемся в инсте и сможем немедленно закончить всю линейку. Так как перезапус занимает около 30 минут, мы можем сэкономить до двух часов."
                                            Ответить
                                            • Имення поэтому, как я няписала в предыдущем комментарии, в реальных ММОРПГ после падения сервера персонажи телепортируются в "безопасные локации" (всякие там города) со сбросом повторяемых квестов/инстансов.
                                              Ответить
                                      • гост течет от теха
                                        Ответить
                              • а проблемы с сетью (дроп / пинг) как планировали решать? экстраполяцией?
                                Ответить
                                • > а проблемы с сетью

                                  До клиентов? Никак, лол. Очень грубая экстраполяция на движение перса (чтобы уж совсем рывками не бежал) и всё.
                                  Ответить
                      • давай подробности про ММОРПГ
                        Ответить
                        • Да обычная выживалка, где можно деревья рубить и всякую хуйню крафтить. В общем-то только это и запилили перед тем как забить, до боёвки дело не дошло.

                          Просто хотелось на чём-то потренироваться с boost::asio.
                          Ответить
    • я тоже делал похожее тестовое задание на заре карьеры, только не про уголки, а вроде про реверси

      там ещё хотели искусственный интеллект и чтоб за два дня

      когда джун и неадекватные собесеры выстраиваются в ряд, получается такое вот затмение
      Ответить
      • > уголки

        Но это не уголки, а странные шахматы! Это другое.
        Ответить
      • В данном конкретном случае у нас не джун, а мудак:) А так всё верно
        Ответить
      • > там ещё хотели искусственный интеллект и чтоб за два дня

        Что-то мне намекает, что потом так и пришлось бы писать уголки с ИИ за 2 дня каждую неделю. Мобильный гейдев такой мобильный.
        Ответить
        • а там вроде и не гейдев даже был

          тз вообще было десктопной приложухой на крестах и на кутэ, потому что я тогда кутэ чуть-чуть знал. был выбор: или вот эта трахомундия, или олимпиадные задачки...
          Ответить
          • я бы нагуглил готовый алгоритм, и реализовал бы

            вот еще выдумывать какие-то мы хорьки очень любим уголки
            Ответить
            • да с такими тз проще нагуглить другие компании и всё
              Ответить
              • хуй знает

                Вообще задача "найти подходящий алгоритм" звучит как хорошая задача для крепкого мидла

                Только на самом собеседовании я бы обосрался со страху конечно, и ничего не сказал

                А дома порылся бы, и наверное нашел как решить
                ---

                Олимпитухи должны наверное такие задачи щелкать

                А я умею решать задачи с "интеллектом" для игр путём перебора: строишь дерево всех возможных вариантов, и всех их обходишь.

                Только это не быстро) зато надежно
                Ответить
                • алгоритм для чего? для реверси?
                  Ответить
                  • ну да, может и для реверси

                    я уже нагуглил
                    https://smekni.com/a/115958/razrabotka-algoritma-i-realizatsiya-igry-reversi/
                    Ответить
                    • ну это надо ещё реализовать и потом оттестировать

                      плюс ии это же не вся игра ещё

                      и код успеть порефакторить от говна

                      и всё это под песню "сегодня вторник, а вот в четверг хотелось бы получить"

                      а сам проверяющий в итоге потом не смог даже запустить, хотя это был обычный кутэшный проект, сбацанный в обычном кутэкреаторе
                      Ответить
            • > я бы нагуглил готовый алгоритм, и реализовал бы

              Для таких умников можно предложить шахматы или го.
              Ответить
              • или такую задачу: есть торговец, и есть несколько сотен городов... и вот карта..
                Ответить
                • нашёл старую школьную тетрадку, в которой расписывал игру, похожую на морровинд. хочу теперь наконец-то сделать. программировать не умею, нужен помощник. время две недели, бюджет $400
                  Ответить
                  • я джва года жду такую игру
                    Ответить
                    • сделайте нам пожалуйста клон слака за 2000 долларов

                      бля, почему до сих пор не постил сюда задания с фриланс-бирж?
                      Ответить
                      • Пишу клон Вконтакте, уже купил шаред хостинг
                        Ищу программистов и админов для поддержки, пока на общественных началах (но выручку разделим)
                        Ответить
                      • вот хорошая задача
                        https://www.weblancer.net/projects/veb-programmirovanie-31/skript-dlya-tilydy-1114471/

                        десять баксов-то не лишние
                        Ответить
                        • https://www.weblancer.net/projects/veb-programmirovanie-31/sozdanie-prodayushego-sajta-dlya-kompanii-doktordez-1114485/

                          ха-ха-ха, какое SEO
                          Ответить
                          • > Все работы проводятся в строгом соответствии с нормами СанПиН только качественными сертифицированными средствами. Гарантированное качество услуг. Приедем в удобное для Вас время. Мы гарантируем высокое качество и низкие цены!
                            Это заказ или спам?
                            Ответить
                            • я вот тоже не могу понять :-)

                              но блин, это подход. если пхп никто не поправит, так хоть прорекламируемся
                              Ответить
                          • это копипваста
                            Ответить
                        • https://www.upwork.com/freelance-jobs/apply/want-someone-who-can-make-high-end-game-for-sales_~0125ccfb1b3ebfaeb4/

                          make a high-end game for sales


                          Fixed-price: $300
                          Ответить
                          • >I want someone
                            Ответить
                            • https://govnokod.ru/user/4722
                              Ответить
                              • Это тян, кстати. или трап. Не помню точно
                                Ответить
                                • Это фуйня из-под коня:
                                  https://www.linux.org.ru/forum/talks/3686890
                                  Ответить
                                  • http://lurkmore.to/Sikon
                                    Ответить
                                    • Не, someone это не Sikon (хотя на самом деле хрен их знает)

                                      Sikon тут тоже был(а), это https://govnokod.ru/user/3764/codes

                                      > Короче, ушла я от вас.
                                      > Не вписываюсь в коллектив, что уж поделаешь. Все плюсуют улюлюкающих троллей и минусуют мои претензии по поводу культуры общения.

                                      Какая драма )))


                                      http://wikireality.ru/wiki/Sikon вот еще какая-то инфа
                                      Ответить
                                      • Ну что, дотроллились? Доулюлюкались? Довольны результатом? Не задумывались о том, чтобы рассмотреть претензии к культуре общения на говнокоде?
                                        Ответить
                                        • А под чью культуру общения ты предлагаешь подстраиваться? Под ротоёба?
                                          Ответить
                                      • если Sikon это lucidfox, то someone это Sikon, потому что lucidfox это someone, это обнаружил кажется икарус, когда дрючил хеши граватара
                                        Ответить
                                        • > если Sikon это lucidfox, то someone это Sikon, потому что lucidfox это someone

                                          Какая транзитивность )))
                                          Ответить
                                          • Я пытался погуглить как это называется, чтобы написать такой же комментарий, но ничего не смог нагуглить. Это реальный пример нужности математики?
                                            Ответить
                                  • забань меня
                                    забань меня полностью
                                    Ответить
                        • https://www.upwork.com/freelance-jobs/apply/Boxing-video-Game-for-ps4-and-xbox_~017be0e08610fa97c9/

                          Тут хотел уже нахрюкнуть, но оказалось, что Rumble in the Jungle was a real thing
                          Ответить

    Добавить комментарий