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

    +2

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    9. 9
    #include <iostream>
    #include <string>
    #include <string_view>
    
    int main() {
      std::string s = "Hellooooooooooooooo ";
      std::string_view sv = s + "World\n";
      std::cout << sv;
    }

    https://alexgaynor.net/2019/apr/21/modern-c++-wont-save-us/
    What's happening here is that s + "World\n" allocates a new std::string, and then is converted to a std::string_view. At this point the temporary std::string is freed, but sv still points at the memory that used to be owned by it. Any future use of sv is a use-after-free vulnerability. Oops! C++ lacks the facilities for the compiler to be aware that sv captures a reference to something where the reference lives longer than the referent. The same issue impacts std::span, also an extremely modern C++ type.

    Запостил: j123123, 24 Апреля 2019

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

    • Так-так-так, Алекс Гей, давай попробуем понять.

      Ты говоришь что s + "ХУй\n" породит настеке временную строку, на которую затем начнет указывать string_view (такой у него оператор "="), и наконец временная строка даст дуба а указатеть останется


      Гей, я верно всё понял?

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

      В стародавние времена String.substring в жобе создавал новый объект.
      То-есть если у нас была строка в 231234 символов, а мы брали у нее сабстринг в 2 символа, то старую строку уносил бабайк GC, а новая была маленькая.

      Очень много кода на это завязалось.

      И тут Оракл (или Сан?) решил: а зачем срать в кучу? Давайте лучше мы будем держать указатель на старую строку и смищение в ней (ну и длину конечно).

      Таким образом от одной большой строки смогут кормиться тысячи мелких подстрочек.

      Сказано -- сделано (в седьмой джаве).
      И весь жабаёбий код который думал что он филигранно вырезал три байта из строки в пару метров, стал держать эту строку навчено.

      Жабаёбы получили ООМ, бросились к профайлерам, а там гигабайты строк лежат, которые они еще позавчера получили, вырезали пару чаров, и думали что все ок. А вот маленький сабстринг большую строку держит.

      Как говорится мал клоп, да вонюч.

      Такой бугор!
      Ответить
      • Всё наоборот. Это раньше так было, а начиная с семёрки substring создаёт новый объект, независимый от существующей строки.
        Ответить
      • Принеси мне, голубчик, пианино из гостиной... я на нем бокал с шампанским оставила.
        Ответить
        • An octopus is flexible enough to enter your mouth, navigate your digestive system and leave through your anus.
          Ответить
          • Если бы у меня такой октопус был, я бы и не женился вовсе.
            Ответить
            • Я правильно понимаю что ты проделываешь это со своей женой?
              А видео есть?
              Ответить
      • Хоть кто-то вспомнил. Это же старый жаваебский прикол.
        Ответить
    • Для фикса добавят ещё десяток типов ссылок...
      Ответить
      • А вообще - это не какая-то новая проблема. Она всегда была для указателей, ссылок и итераторов. Если объект менялся или дох - они превращались в тыкву.

        Странно было бы, если бы string_view, который создан как быстрая обёртка над куском существующей строки, работал иначе.
        Ответить
        • > А вообще - это не какая-то новая проблема. Она всегда была для указателей, ссылок и итераторов. Если объект менялся или дох - они превращались в тыкву.

          Вот именно поэтому я за Си. Там ничего просто так не дохнет.
          #include <string.h>
          #include <stdio.h>
          #include <stdlib.h>
          
          int main()
          {
            const char a[] = "Hellooooooooooooooo ";
            const char b[] = "World\n";
            char *c = malloc(strlen(a)+strlen(b)+1);
            if(c == NULL) return EXIT_FAILURE;
            strcat(strcat(c,a), b);
            puts(c);
            free(c);
            return EXIT_SUCCESS;
          }
          Ответить
          • Вот только use-after-free у сишников почему-то встречается не реже.
            Ответить
            • Это у анскильных питухов встречается, а Цари помнят, когда они что освобождали.
              Ответить
            • Мне кажется что достаточно иметь внятный контракт чтобы понимать что и когда освобождаетс
              Ответить
              • Вполне достаточно.

                У каждой функции как правило внятный контракт. Иногда даже на уровне одной либы они совпадают. Но в целом, когда у тебя в проге юзается несколько либ - это лютый треш, о котором постоянно надо думать.

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

                  Конечно, про это приходится постоянно думать. Зато мемори футпринт под контролем, не то что в жабах
                  Ответить
                  • > мемори футпринт под контролем
                    В крестах его держать под контролем ничуть не сложнее, имхо.

                    > пример треша
                    Да банально - в одной либе тебе возвращают хуйню, на которой ты должен LocalFree, во второй - просто free, в третьей - HuiPizdaFree. Где-то надо самому буфер подготовить (и позвать перед этим с нулём для оценки размера). Где-то тебе вернут указатель на кишки структуры который вообще удалять нельзя. Каждая либа вроде и консистентна, но в целом по проекту выходит каша.

                    Вот в том же openssl даже в пределах одной либы не всегда понятно надо ли освобождать поинтер. Благо в последних версиях они эту инфу в сигнатуру функций стали включать...

                    Вот здесь и спасают крестообёртки и крестосмартпоинтеры.
                    Ответить
                    • > Вот здесь и спасают крестообёртки и крестосмартпоинтеры.

                      Так и запишем - C++ это язык для подкостыливания сишечки.
                      Ответить
                      • Он же изначально с этой целью и создавался ;)
                        Ответить
                        • Ну то понятно, только вот его зачем-то пытаются сделать чем-то бОльшим, чем набор костылей к сишечке. Но из говна конфетку не сделаешь.
                          Ответить
                          • В общем кресты можно рассматривать даже не как самостоятельный язык, а как набор стандартизированных кривых сишных экстеншнов(которые к тому же в разных компиляторах реализованы часто не до конца, слегка по-разному и с кучей всяких багов, которые обходят всякими кривыми костылями во всяких там бустах), названный по ошибке новым языком. Впрочем, название "C++" на это явно намекает
                            Ответить
                            • Крестошаблоны уже можно назвать отдельным языком. С тем же успехом можно назвать языком команды так называемой «turtle graphics» в операторе DRAW «Бейсика», ноты в операторе PLAY «Бейсика» же, и закорючки форматной строки в вызове функции printf в сишке.
                              Ответить
                              • А сишный препроцессор это отдельный язык?
                                Ответить
                                • Конечно! Борманд на нём AES реализовал:
                                  https://github.com/bormand/pp_aes
                                  Ответить
                                  • Какой багор )))
                                    Ответить
                                  • https://github.com/bormand/govnokod-board

                                    > Превращает govnokod.ru в анонимную борду

                                    Можно говносток и хуз сделать анонимными.
                                    Ответить
                                    • Чего мелочиться, пусть Страйко сделает.
                                      Ответить
                                      • Кинул страйк на твой Youtube-канал, проверь.
                                        Ответить
                      • Страуструп словно ортопед, который пытается выправить пациента.
                        Только аппарат Илизарова он не снимает уже очень долго, всё подкручивает к нему шурушки.
                        Ответить
                    • >В крестах его держать под контролем
                      надо всегда понимать что у тебя там копируется, двигается итд
                      Ответить
                    • >HuiPizdaFree
                      Если есть HuiPizdaFree то есть и HuiPizdaAlloc, не?

                      Код получается сбалансированный:

                      Petux p = createPitux();
                      ///////
                      dropPitux(p);
                      и всё просто.

                      Ну да, надо каждый раз изучать контракт, но мне кажется это не самое тяжкое в мире
                      Ответить
                  • Особая боль - чтение асинхронного сишного кода. Сишник, который его писал, само собой учёл все 100500 ивентов по которым надо фришить структуры или их куски.

                    Блядь, как у вас хватает на это памяти и внимания!? И ещё остаётся на суть задачи...
                    Ответить
                    • >чтение асинхронного сишного кода.
                      Это да, тут надо плодить абстракции чтобы они все за тебя делали
                      Ответить
          • #include <string.h>
            #include <stdio.h>
            #include <stdlib.h>
            
            int main()
            {
              const char a[] = "Hellooooooooooooooo ";
              const char b[] = "World\n";
              char *c = malloc(strlen(a)+strlen(b)+1);
              if(c == NULL) return EXIT_FAILURE;
              c[0] = 0; // пофиксил
              strcat(strcat(c,a), b);
              puts(c);
              free(c);
              return EXIT_SUCCESS;
            }
            Ответить
            • @char *c = malloc(strlen(a)+strlen(b)+1);
              @if(c == NULL) return EXIT_FAILURE;

              А разве аллокатор молча не швыряет исключение?
              Хм. Погуглил. Инфы по CRT крайне мало, но я полагаю, что это обёртка над VirtualAlloc. Тогда тем более нужен обработчик, швыряющий исключение при неудачном вызове.
              Ответить
              • «new» — швыряет.
                «new (std::nothrow)» — не швыряет, возвращает «nullptr».
                «malloc»/«calloc» — не швыряют, возвращают «NULL».

                Ну и j123123 привёл пример на «C», в нём нет никаких «исключений», и именно поэтому я за.
                Ответить
                • у МС в си есть исключения на основе longjmp/setjmp
                  Ответить
                • То есть, как это нет? А try.. catch..throw?


                  procedure malloc(var P:Pointer; Size:DWORD);
                  begin
                  P:=Pointer(GlobalAlloc(GPTR, Size));
                  if P=nil then
                  raise ENotEnoughMemException.Create('Вы соснули с заглотом');
                  end;
                  Ответить
                  • Это не си.

                    В ISO C исключений нет.
                    Есть рашсирение копулятора от MS на основе setjmp/longjmp
                    Ответить
                    • Спасибо, кэп, я знаю, что не си. Код только для примера.
                      Речь вообще-то идёт о try.. catch..throw
                      Ответить
                      • 1. try.. catch..throw это и есть исключения
                        2. в си нету try.. catch..throw
                        Ответить
                        • Есть нестандартные расширения: в «MSVC» и в «Watcom C» есть __try...__except и __try...__finally. Работает только в «Windows», потому что гвоздями прибито к «SEH».
                          Ответить
                          • И Было Сказано
                            "Есть рашсирение копулятора от MS на основе setjmp/longjmp"
                            Ответить
                            • setjmp/longjmp тут могут оказаться ни при чём.
                              Ответить
                              • Я настроил контрастность. см.

                                * * u n s k i l l * * u n s k i l l * * u n s k i l l * *
                                u                                                       u
                                n                   ▄▄▄▄██████▄▄  ▄█████▄▄▄             n
                                s                ████████████████▄███████████           s
                                k              █████████████████▌▐█████████████         k
                                i            ████████████████▀      ▀████████████       i
                                l           █████████████▀▀            ▀█████████▌      l
                                l          ████████▀▀                     ▀███████▌     l
                                *         ▐██████▌   -,___          ___,-  ▐█████▌      *
                                u        ▐██████▌    _____`-,    ,-'____    ▐█████▌     u
                                n        ▐█████▌    /     \        /    \   ▐█████▌     n
                                s        ▐█████▌   |    O  |   \  |   O  |  ▐█████▌     s
                                k       ▐██████▌    \_____/     \  \____/   ▐█████▌     k
                                i       ▐██████▌                 \          ▐█████▌     i
                                l      ▐███████▌                  \         ▐█████▌     l
                                l     ██████████▌              ---`         ▐██████▌    l
                                *    ▐████████████     `:---______---:`     ▐██████▌    *
                                u    ▐█████████████     `,| |  |  | |'     ▐███████▌    u
                                n   ▐███████████████      ``''''''''      ██████████▌   n
                                s   ▐██████████████████                █████████████▌   s
                                k  ▐█████████████████████------------████████████████▌  k
                                i  ▐█████████████████████▌          ▐████████████████▌  i
                                l ▐██████████████████████▌          ▐█████████████████▌ l
                                l ▐█████████████████████▌            ▐████████████████▌ l
                                * * u n s k i l l * * u n s k i l l * * u n s k i l l * *
                                Ответить
                                • * * u n s k i l l * * u n s k i l l * * u n s k i l l * *
                                  u                                                       u
                                  n                   ▄▄▄▄██████▄▄  ▄█████▄▄▄             n
                                  s                ████████████████▄███████████           s
                                  k              █████████████████▌▐█████████████         k
                                  i            ████████████████▀      ▀████████████       i
                                  l           █████████████▀▀            ▀█████████▌      l
                                  l          ████████▀▀                     ▀███████▌     l
                                  *         ▐██████▌   -,___          ___,-  ▐█████▌      *
                                  u        ▐██████▌    _____`-,    ,-'____    ▐█████▌     u
                                  n        ▐█████▌    /     \        /    \   ▐█████▌     n
                                  s        ▐█████▌   |    O  |   \  |   O  |  ▐█████▌     s
                                  k       ▐██████▌    \_____/     \  \____/   ▐█████▌     k
                                  i       ▐██████▌                 \          ▐█████▌     i
                                  l      ▐███████▌                  \         ▐█████▌     l
                                  l     ██████████▌              ---`         ▐██████▌    l
                                  *    ▐████████████     `:---______---:`     ▐██████▌    *
                                  u    ▐█████████████     `,| |  |  | |'     ▐███████▌    u
                                  n   ▐███████████████      ``''''''''      ██████████▌   n
                                  s   ▐██████████████████                █████████████▌   s
                                  k  ▐█████████████████████------------████████████████▌  k
                                  i  ▐█████████████████████▌          ▐████████████████▌  i
                                  l ▐██████████████████████▌          ▐█████████████████▌ l
                                  l ▐█████████████████████▌            ▐████████████████▌ l
                                  * * u n s k i l l * * u n s k i l l * * u n s k i l l * *
                                  Ответить
                                  • * * u n s k i l l * * u n s k i l l * * u n s k i l l * *
                                    u                                                       u
                                    n                   ▄▄▄▄██████▄▄  ▄█████▄▄▄             n
                                    s                ████████████████▄███████████           s
                                    k              █████████████████▌▐█████████████         k
                                    i            ████████████████▀      ▀████████████       i
                                    l           █████████████▀▀            ▀█████████▌      l
                                    l          ████████▀▀                     ▀███████▌     l
                                    *         ▐██████▌   -,___          ___,-  ▐█████▌      *
                                    u        ▐██████▌    _____`-,    ,-'____    ▐█████▌     u
                                    n        ▐█████▌    /     \        /    \   ▐█████▌     n
                                    s        ▐█████▌   |    O  |   \  |   O  |  ▐█████▌     s
                                    k       ▐██████▌    \_____/     \  \____/   ▐█████▌     k
                                    i       ▐██████▌                 \          ▐█████▌     i
                                    l      ▐███████▌                  \         ▐█████▌     l
                                    l     ██████████▌              ---`         ▐██████▌    l
                                    *    ▐████████████     `:---______---:`     ▐██████▌    *
                                    u    ▐█████████████     `,| |  |  | |'     ▐███████▌    u
                                    n   ▐███████████████      ``''''''''      ██████████▌   n
                                    s   ▐██████████████████                █████████████▌   s
                                    k  ▐█████████████████████------------████████████████▌  k
                                    i  ▐█████████████████████▌          ▐████████████████▌  i
                                    l ▐██████████████████████▌          ▐█████████████████▌ l
                                    l ▐█████████████████████▌            ▐████████████████▌ l
                                    * * u n s k i l l * * u n s k i l l * * u n s k i l l * *
                                    Ответить
                                    • * * u n s k i l l * * u n s k i l l * * u n s k i l l * *
                                      u                                                       u
                                      n                   ▄▄▄▄██████▄▄  ▄█████▄▄▄             n
                                      s                ████████████████▄███████████           s
                                      k              █████████████████▌▐█████████████         k
                                      i            ████████████████▀      ▀████████████       i
                                      l           █████████████▀▀            ▀█████████▌      l
                                      l          ████████▀▀                     ▀███████▌     l
                                      *         ▐██████▌   -,___          ___,-  ▐█████▌      *
                                      u        ▐██████▌    _____`-,    ,-'____    ▐█████▌     u
                                      n        ▐█████▌    /     \        /    \   ▐█████▌     n
                                      s        ▐█████▌   |    O  |   \  |   O  |  ▐█████▌     s
                                      k       ▐██████▌    \_____/     \  \____/   ▐█████▌     k
                                      i       ▐██████▌                 \          ▐█████▌     i
                                      l      ▐███████▌                  \         ▐█████▌     l
                                      l     ██████████▌              ---`         ▐██████▌    l
                                      *    ▐████████████     `:---______---:`     ▐██████▌    *
                                      u    ▐█████████████     `,| |  |  | |'     ▐███████▌    u
                                      n   ▐███████████████      ``''''''''      ██████████▌   n
                                      s   ▐██████████████████                █████████████▌   s
                                      k  ▐█████████████████████------------████████████████▌  k
                                      i  ▐█████████████████████▌          ▐████████████████▌  i
                                      l ▐██████████████████████▌          ▐█████████████████▌ l
                                      l ▐█████████████████████▌            ▐████████████████▌ l
                                      * * u n s k i l l * * u n s k i l l * * u n s k i l l * *
                                      Ответить
              • у CRT сырцы естьв ащето
                Ответить
                • Не нашёл сорян. Я напутал чуть. VirtualAlloc - это резервация памяти в файле подкачки. Тогда на ум приходит разве что HeapAlloc - самая быстрая память.
                  Ответить
                  • Не причем тут файл подкачки совершенно, ты на это вообще никак не влияешь.

                    VirtualAlloc выделяет страницы в виртуальной памяти. HeapAlloc это реализация менеджера куч поверх этого. Она позвляет не гранулировать по страницам, но не позволяет резервировать например.

                    Сырцы СРТ ставятся с сдк или студией
                    Ответить
                    • Хорошо, а что в твоём понимании "виртуальная память"?
                      Ответить
                      • Адресное пространство процесса и механизмы его реализации железом и ОС

                        Файл подкачки можно вообще отключить, виртуальная память никуда не денется, лишь бы RAM хватило.
                        Ответить
                        • За слова надо отвечать, гость.
                          https://docs.microsoft.com/en-us/previous-versions/ms810627(v=msdn.10)

                          When memory is committed, physical pages of memory are allocated and space is reserved in a pagefile.
                          Ответить
                          • А тебе нужно научиться читать чуть дальше,.

                            memory always exist as either physical pages of memory or as pages that have been paged to the pagefile on disk

                            Если у тебя не хватает места в RAM то конечно операционка застолбит место в свапе.
                            Если же места хватает и свапа нет то место застолбится в памяти.

                            Ты никак не влияешь на то, куда попадет твоя страница. Этим занимается менеджер виртуальной памяти.
                            Ответить
              • malloc –— это не просто обёртка. Это может быть собственная куча CRT.

                CRT может при старте вызвать VirtualAlloc (или ещё какой-нибудь ...Alloc) с запасом, а потом вызывать не на каждый malloc, а по необходимости. Внутри куска, выделенного VirtualAlloc, CRT может вводить свою разметку.
                Ответить
                • P.S. Есть альтернативные реализации malloc: jemalloc, dmalloc, hoard, tcmalloc:
                  https://en.wikipedia.org/wiki/C_dynamic_memory_allocation#Implementati ons

                  Если бы функция malloc была тупой обёрткой, столько реализаций не появилось бы.
                  Ответить
                  • показать все, что скрытоВ общем есть API операционки. Это сискол brk в прыщах или VirtualAlloc в сперме.

                    Поверх него есть много разных способов сделать кучу. Это может быть HeapAlloc в мастдае или malloc в glibc в прыщах или в CRT в пинде. Или new в крестах.
                    Ответить
                  • зы: на счет прыщей мог спизднуть, возможно там это поверх mmapа сделано, но оба интерфейсы к подсистеме виртуальной мамяти, так что поъх
                    Ответить
                • Угу. В релизной конфигурации, к примеру, оно вызывает «HeapAlloc»:
                  // This function implements the logic of malloc().  It is called directly by the
                  // malloc() function in the Release CRT and is called by the debug heap in the
                  // Debug CRT.
                  //
                  // This function must be marked noinline, otherwise malloc and
                  // _malloc_base will have identical COMDATs, and the linker will fold
                  // them when calling one from the CRT. This is necessary because malloc
                  // needs to support users patching in custom implementations.
                  extern "C" __declspec(noinline) _CRTRESTRICT void* __cdecl _malloc_base(size_t const size)
                  {
                      // Ensure that the requested size is not too large:
                      _VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr);
                  
                      // Ensure we request an allocation of at least one byte:
                      size_t const actual_size = size == 0 ? 1 : size;
                  
                      for (;;)
                      {
                          void* const block = HeapAlloc(__acrt_heap, 0, actual_size);
                          if (block)
                              return block;
                  
                          // Otherwise, see if we need to call the new handler, and if so call it.
                          // If the new handler fails, just return nullptr:
                          if (_query_new_mode() == 0 || !_callnewh(actual_size))
                          {
                              errno = ENOMEM;
                              return nullptr;
                          }
                  
                          // The new handler was successful; try to allocate again...
                      }
                  }
                  Ответить
                  • А в дебаге через пару обёрток вызывается «heap_alloc_dbg»:
                    // Allocates a block of size bytes from the debug heap, using the new handler if
                    // it is configured for use with malloc.
                    static void* __cdecl heap_alloc_dbg(
                        size_t      const size,
                        int         const block_use,
                        char const* const file_name,
                        int         const line_number
                        ) throw()
                    {
                        bool const should_call_new_handler{_query_new_mode() != 0};
                        for (;;)
                        {
                            void* const block{heap_alloc_dbg_internal(size, block_use, file_name, line_number)};
                            if (block)
                                return block;
                    
                            if (!should_call_new_handler || !_callnewh(size))
                            {
                                errno_t* const global_errno{_errno()};
                                if (global_errno)
                                    *global_errno = ENOMEM;
                    
                                return nullptr;
                            }
                    
                            // The new handler was successful -- try to allocate again
                        }
                    }


                    А «heap_alloc_dbg_internal» оперирует двусвязным списком вот таких штруктур:
                    //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    //
                    // Types
                    //
                    //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    // For diagnostic purpose, blocks are allocated in the debug heap with extra
                    // information and stored in a doubly-linked list.  This makes all blocks
                    // registered with how big they are, when they were allocated, and what they are
                    // used for.
                    struct _CrtMemBlockHeader
                    {
                        _CrtMemBlockHeader* _block_header_next;
                        _CrtMemBlockHeader* _block_header_prev;
                        char const*         _file_name;
                        int                 _line_number;
                    
                        int                 _block_use;
                        size_t              _data_size;
                    
                        long                _request_number;
                        unsigned char       _gap[no_mans_land_size];
                    
                        // Followed by:
                        // unsigned char    _data[_data_size];
                        // unsigned char    _another_gap[no_mans_land_size];
                    };
                    Ответить
                    • што токое throw()?
                      Это вообще няшная или кресты?

                      Вощим в рилизе этотакая интеллигентная надстроечка над HeapAlloc, а в дебажной там много всего дебажного чтобы легче ловить баги
                      Ответить
                      • > што токое throw()?
                        Это такой noexcept в старых крестах.

                        > Это вообще няшная или кресты?
                        Кресты. Микрософтный CRT на них написан.
                        Ответить
    • нашли до чего доклепаться
      Ответить
    • https://habr.com/ru/post/449368/ Нужно ли чистить строки в JavaScript?
      > Суть проблемы

      > В общем, оказывается, что строки содержат ссылки на родительские строки! Что??

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

      > Получается такая цепочка указателей:
      > какой-то массив или объект -> ваша новая маленькая строка -> старая большая строка
      > На самом деле всё ещё сложнее, у строки может быть несколько «родителей», но не будем усугублять.
      Ответить
      • Поэтому я за Си - там нет никакой неявной хуйни со строками, все четко и дерзко
        Ответить
      • О, очередные абсракции потекли.
        Ответить
      • Можно научить сборщик мусора оценивать КПД ссылок на старые строки. Типа если строка весит метр, а нарезанные из неё куски весят джва - всё ок. А если выжила всего пара мелких фрагментов - можно их скопировать и ёбнуть оригинал.
        Ответить
        • На оценку нужны ресурсы процессора. GC же вроде и придумали для того, чтобы реже чистить.
          Ответить
          • GC придумали чтобы программистам не надо было думать об освобождении памяти.
            Ответить
            • Теперь программистам надо думать о том, чтобы GC начал думать об освобождением памяти
              Ответить
              • Раньше программистам надо быо думать только про память
                теперь еще про память и гц
                Ответить
                • Поэтому я за Brainfuck на бесконечной ленте. Там память бесконечна, и о ней можно не думать
                  Ответить
                  • Несколько лет назад была мода тупо выпиливать GC из этих ваших рантаймов. Типа, память ожидаемо кончается, и ваша stateless питушня периодически рестартуется. To же самое говорил и фельдмаршал Конрад фон Гетцендорф: "Die AWS Instanzen mussen so wie so krepieren"
                    Ответить
                    • есть даже какая-то жабка без гц
                      типа зачем тратить времяна гц когд правда можно все перезапустить


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

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