Няшная / Говнокод #17227 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
char *stringFromDTM(MDTM *dtm)
{
    if (dtm->count < 1)
    return "";
    uint32_t size = (sizeof(MDTMPoint) + sizeof(uint32_t)) * dtm->count;
    void *data = calloc(1, size);
    uint32_t *ptr = data;
    *(ptr++) = size;
    uint32_t index;
    for (index = 0; index < dtm->count; index++)
    *(ptr++) = dtm->points[index].x;
    for (index = 0; index < dtm->count; index++)
    *(ptr++) = dtm->points[index].y;
    for (index = 0; index < dtm->count; index++)
    *(ptr++) = dtm->points[index].color;
    for (index = 0; index < dtm->count; index++)
    *(ptr++) = dtm->points[index].tol;
    for (index = 0; index < dtm->count; index++)
    *(ptr++) = dtm->points[index].size;
    for (index = 0; index < dtm->count; index++)
    *(ptr++) = dtm->points[index].x;
    bool *bptr = (bool *)ptr;
    for (index = 0; index < dtm->count; index++)
    *(bptr++) = dtm->points[index].bad;
    uint32_t len = compressBound(size);
    char *buffer = malloc(len);
    if (compress((Bytef *)buffer, (uLongf *)&len, data, size) == Z_OK)
    {
        free(data);
        char *compressed = malloc(len + sizeof(uint32_t));
        *((uint32_t *)(compressed)) = len;
        strcpy(compressed + sizeof(uint32_t), buffer);
        free(buffer);
    }
    free(buffer);
    free(data);
    return "";
}

Я так и не раскурил, почему так, а не иначе.

Запостил: Cynicrus Cynicrus, (Updated )

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

  • Строки 5-6. Всегда прикалывало. Интерфейсом calloc(num, size) никто не пользуется.

    Пару раз в качестве стилевого эксперимента пытался передавать calloc() оба параметра без предварительного умножения, но как-то не прижилось.

    PS strcpy() на потенциально двоичные данные? выглядит загадочно. (и да, данные скорее всего двоичные, потому что Z_OK это скорее всего код возврата GNU zip'ного libz.)
    Ответить
    • Еще прикольно, что возвращается всегда "". Т.е. функция бесполезна.
      Ответить
  • Как оно работает, если тут дважды вызывается free для buffer и data?
    Ответить
    • Видимо между строками 33 и 34 проебался return compressed.

      Вот, кстати, еще красивое говно: функция возвращает то литерал "" (который не надо освобождать) то буфер (который надо освободить). Всё для удобства вызывающего!
      Ответить
      • > Всё для удобства вызывающего!
        Особенно с учетом того, что в начале compressed'а лежит длина, у которой с вероятностью 1/256 (если little-endian архитектура) нолик в первом байте... Как они собираются отличать этот буфер от "" - хуй знает. Скорее всего так:
        char *result = stringFromDTM(dtm);
        if (result == "") { // не повторяйте это дома!
            // ...
        }
        Ответить
          • Тип того. Но никаких гарантий, т.к. это всего лишь оптимизация для экономии места. Пользоваться этой фичей нельзя.
            Ответить
            • Теоретически пустая строка в сишечке может быть и нулевым указателем; и указателем на произвольный нулевой байт, лежащий где угодно (который можно сравнивать только через строковые функции); и специально подготовленным указателем на первую нулевую константу исполнимого модуля*, для которой сравнение с "" не лишено смысла.

              По-моему, маловато видов пустых строк... Надо ещё что-нибудь добавить.

              -----
              * При включенной оптимизации и при некоторых предположениях о линкере.
              Ответить
              • > Теоретически пустая строка в сишечке может быть и нулевым указателем
                Данунахуй? А посоны и не знали.

                > указателем на произвольный нулевой байт, лежащий где угодно
                Именно так. А вот будет ли этот байт одним и тем же для каждого литерала - знают только линкер и компилятор.

                P.S. А еще в древних гцц (3.х) была дурацкая опция -fwritable-strings.
                Ответить
                • Хе, в gcc 3.x еще одна забавная опция нашлась: -fthis-is-variable. Любители присваивать this будут довольны...
                  Ответить
                  • На 3.4 уже выпилили... Лучшее, что нашлось - 2.95, там оно депрекейтед, но еще работает:
                    void foo() {
                        test **t  = &this;
                        *t = new test(42);
                        bar(); // метод, на который эта херня всё-таки повлияет
                    }
                    Ответить

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

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8