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

    −3

    1. 1
    for(;;){new int;}

    Запостил: GC1, 26 Апреля 2016

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

    • ну так прибери, хули на говнокодике сидишь!
      Ответить
    • вот, пофиксил проблему производительности:
      for(;;){new int[128];}
      Ответить
      • Пофиксил ещё больше
        throw bad_alloc;


        (В конце концов адресное пространство кончится и в любом случае исключение вылетит)
        Ответить
        • результаты теста: FAIL. потому что еще за долго до конца адресного пространства закончится физическая память и своп.

          ЗЫ я по тупости к слову ГК скомпилил и запустил... я не просто так проблему производительности фиксил. я эту проблему видел: оригинальному коду нужно секунд 5 что бы 8ГБ памяти съесть. поэтому и фикс.
          Ответить
          • не силен в крестах, но разве сборщик мусора не будет следом подчищать не используемые переменные?
            Ответить
            • Так толсто, что тонко.
              Ответить
            • Так и есть. Приходит оом-киллер и собирает мусор.
              Ответить
              • Правда, иногда он приходит не к тому... Но это мелочи.
                Ответить
            • Как только цикл закончится, всё сразу будет убрано.
              Ответить
          • Хм. В никсах вроде как память физически не выделяется пока её не потрогают. Можно терабайтами выделять.

            А в винде ты даже конца свопа можешь не дождаться из-за диких тормозов.
            Ответить
            • И да, если кончатся и физическая память и своп должно исключение таки вылететь, если ось процесс не прибьёт раньше.
              Ответить
              • и на самом деле. не инициализированая память занимает только виртуальную память, но не физическую.

                к слову. а вы когда-нибудь задумывались об организационных издержках динамического управления памяти? (ну это так, толстый намек.)
                Ответить
                • Здесь просто выделение же, working set не такой и большой (только те странички, которые трогает аллокатор) Так что, в теории, должно просраться и ожить через несколько минут, даже в линухе...

                  А вот если все эти инты реально юзать...
                  Ответить
                  • попробуй просто сам динамический аллокатор написать, и потом посмотри сколько памяти будет трогатся - и писатся - при выделении памяти. не забывать: каждый отдельно выделеный int можно отдельно освобождать.
                    Ответить
                    • const size_t PEKA = 64;
                      const size_t YOBA = 100500;
                      char *small_kucha = new char[PEKA * YOBA];
                      std::vector<bool> zanyato(YOBA, false);
                      
                      void *malloc(size_t skolko) {
                        if (skolko <= PEKA) {
                           auto svobodno = std::find(zanyato, false);
                           if (svobodno != zanyato.end()) {
                             *svobodno = true;
                             return small_kucha[PEKA * (svobodno - zanyato.begin())];
                           }
                        }
                        return mmap(0, skolko, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
                      }
                      Ответить
                      • хм. интересно. очень интересно. а free() где?
                        Ответить
                        • void free(void *pamyat) {
                            char *pamyat2 = static_cast<char*>(pamyat);
                            if (pamyat2 >= small_kucha.data() && (pamyat2 - small_kucha.data()) < small_kucha.size()) {
                              zanyato[(pamyat2 - small_kucha.data()) / PEKA] = false;
                            } else {
                              // надо сделать munmap
                            }
                          }
                          Ответить
                        • free() тривиален же.
                          Если указатель внутри small_kucha, рассчитать номер блока и поставить флажок. Иначе - munmap. Правда, для unmap нужно хранить длину.
                          void free(void* p) {
                            if (!p) return;
                            auto ptr = static_cast<char*>(p);
                            auto L = begin(small_kucha), R = end(small_kucha);
                            if (ptr >= L && ptr < R) {
                              auto offset = (ptr - L) / PEKA;
                              if (L + offset != ptr) {
                                terminate("WUT?!");
                              }
                              zanyato[offset] = false;
                            } else {
                              munmap(ptr, length_of(ptr));
                            }
                          }
                          Ответить
                          • > free() тривиален же.

                            лень думать.

                            > Правда, для unmap нужно хранить длину.

                            на линухе можно просто грепнуть мапы процесса что бы найти сколько памяти было мапнуто. между блоками как правило есть немапнутые странички как разграничители.
                            Ответить
                      • Нейминг знатный. Не хватает переменных bugurt, kokoko, ololo и pitux.
                        Ответить
                    • > попробуй просто сам динамический аллокатор написать
                      Писал. На паттерне из топика он бы трогал только свежие странички. Тут же удалений никаких нету, дырок нету, оббегать нечего.
                      Ответить
            • Ты уверен, что если выделять память интами, то аллокатор не потрогает большую часть страниц?
              Ответить
    • Течёт.
      Ответить
    • а вообще, надо for(;;) new int(0);
      Ответить
      • Без скобочек пишут только пидоры.
        Ответить
        • И символ ктулху for(;;) вместо while (true) - тоже.
          Ответить
          • Как-то раз тимлид исправил в моем коммите while (true) на for (;;). Я постеснялся спросить, зачем.
            Ответить
            • Еще он часто без скобочек пишет. Получается, мой тимлид - пидор.
              Ответить
              • > Получается, мой тимлид - пидор.
                А если он ещё и читает ГК, то завтра ты ощутишь это на своей жопе...
                Ответить
                • К счастью, на работе никто не знает, что курва - это один из моих псевдонимов.
                  Ответить
                  • Кстати, почему никто не подкатывает к курве? У нее же ник - курва.
                    Ответить
                    • Потому что мальчиков на этом сайте любишь только ты
                      Ответить
                      • Да нихуя, вон вася от пердака оторваться не может.
                        Ответить
            • Больше символов - больше заплатят
              Ответить
            • Какой-то компилятор ругался что условие в цикле всегда true и рекомендовал for (;;). Но я просто варнинг отключил и пишу while(1).
              Ответить
        • еще я ради пидоров скобочки не ставил
          Ответить

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