1. Си / Говнокод #12360

    +111

    1. 1
    2. 2
    for(p=first; p!=NULL; p=p->next)
      free(p);

    Освобождаем память всех элементов списка.

    Запостил: taburetka, 26 Декабря 2012

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

    • Есть ли жизнь после free? Все еще вопрос веры, а не науки? :)
      Ответить
    • next, видимо, расположен не в начале структуры? Иначе автор бы автор сразу заметил, в чем он накосячил...
      Ответить
      • >не в начале структуры? Иначе автор бы автор сразу заметил
        Это почему это?
        Ответить
        • При вызове free аллокатор может поместить в начало, и возможно, в конец блока свою служебную инфу, которую и прочитал бы цикл, на следующей итерации...

          З.Ы. но вроде бы гццшный так не делает, поэтому ты прав, не заметит...
          Ответить
          • Нет ты прав!
            Ответить
          • редкий аллокатор это делает (потому что служебной инфы надо очень мало). пасквилисты должны это фишку еще помнить.

            Сшный аллокатор для каждого выделенного блока уже предусматривает место для служебной информации - что-то типа размера выделенного блока. Пасквальный аллокатор был крут и никакой служебной инфы к блоку не добавлял - но требовал что бы код при выделении "помнил" сколько именно памяти было выделено.

            с другой стороны, любой мемори дебаггер этот код споймает. даже мой доморощеный - который заполняет освобождаемые блоки poison pattern'ом.
            Ответить
            • > но требовал что бы код при выделении "помнил" сколько именно памяти было выделено.

              Всё было ещё пиздецовее, на самом деле.
              type
                intarr = array [0..high(word)/sizeof(int)-2] of integer;
              var
                pi : ^intarr;
                p : pointer;
              begin
                getmem(pi, 100);
                {freemem(pi); }{ жопа будет, он попытается удалить sizeof(intarr) памяти}
                p := pi;
                freemem(p); { всё корректо}
              Ответить
              • Ну собственно смешивание непарных аллокатора и деаллокатора никогда хорошо не кончались. Вспомни крестовые delete и delete[] для неподов.

                Другое дело, что в паскале два несовместимых механизма назвали одним именем... в этом и жопа.
                Ответить
                • >в паскале два несовместимых механизма назвали одним именем
                  такая вот перегрузка
                  Ответить
              • Хм, покурил про эти гетмемы.

                getmem и freemem без указания размера это, получается, фишка gnu pascal?

                А у Борланда были только getmem и freemem с задаваемыми вручную размерами, поэтому этот код там тупо не скомпилится?
                Ответить
                • Кажется, в моём примере вместо FreeMem надо писать Dispose
                  Но пиздец тут в том, что это разные функции для типизированного и нетипизированного указателей!
                  Ответить
                  • Пиздец тут в голове программиста, пишущего такой код (выделяющий getmem а освобождающий dispose, или выделяющий new а освобождающий freemem) а не в языке и либе.

                    В крестах free, delete и delete[] для неподов тоже дадут разный результат. И все нормальные программисты используют только парные функции.
                    Ответить
    • а можете объяснить неучу в чем здесь говнокод помимо того что сказал bormand про размещение служебных блоков в освобожденной памяти?
      Ответить
      • Ну собственно в том что в ходе выполнения цикла сначала убьётся элемент вызовом free(p) а потом уже убитый элемент потрогают при выполнении p=p->next.
        Такая некрофилия до добра не доводит.
        Ответить
      • В использовании undefined behavior - работе с блоком памяти после его освобождения. Каждый ub это как ружье висящее на стене, которое обязательно выстрелит. Может быть на текущей архитектуре и компиляторе все работает, но это совершенно ничего не значит и не гарантирует
        .

        Самое плохое что может случиться - это то, что этот код будет работать без ошибок.
        Ответить
    • Вот из-за такого говнокода в Sim City авторам Windows 95 и пришлось переписывать аллокатор.
      Ответить

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