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

    +8

    1. 1
    2. 2
    3. 3
    4. 4
    n = strlen(pName);
    name = new char[n + 1];
    memset(name, 0, n + 1);
    memcpy(name, pName, n);

    боянчик. std::string наверное религия не позволяет. а strdup() слишком С. oh wait...

    Запостил: Dummy00001, 09 Октября 2013

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

    • > strdup() слишком С
      Слишком POSIX. В стандартах c/c++ такой функции нет...

      А вот нахрена там memset я так и не понял... Ради зануления одного байтика в конце? :)
      Ответить
      • > нахрена
        это прогрев выделенного буфера, чтобы новые данные в него затем быстро писались
        Ответить
        • показать все, что скрытоdefecate-plusplus, жжошь! )))
          Ответить
        • >это прогрев выделенного буфера, чтобы новые данные в него затем быстро писались
          это же неправильный способ. Все же знают, что надо прогревать белым шумом.
          Ответить
          • Желательно, сгенерированным колебаниями стрелки аналогового осциллографа. Аналоговые теплее, поэтому прогрев будет эффективнее.
            Ответить
          • Прогревать буфера надо газовой горелкой
            Ответить
            • >газовой горелкой
              Ты фашист.

              Вот еще полутоновый, с французским звучанием
              http://higgs.rghost.ru/46926704/image.png
              код в одном потоке с формой.
              Ответить
    • это больше на чистую С похоже, вернее чисто С код. на кой юзать мемцпи для копинга строк, если есть стрнцпи.

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

          тагда зачем она туда впихнута, если для определенных целей есть своя функция ее и нада юзать, непойму.
          Ответить
          • Кто, куда и зачем впихнута?

            memcpy в данном случае вполне адекватная замена strcpy/strncpy: мы знаем размер блока данных, который нам надо скопировать.
            Ответить
            • strcpy зачем впихнута, если как тут утверждают, лучше (в теории) будет мемцпи.

              ну это вопрос скорее к разрабам либы.)
              Ответить
              • тормозишь? в отличии от memcpy(), strcpy()/strncpy() останавливаются на нулевом символе.
                Ответить
                • это я с пеленок знаю, дело в том что для копировки строки можно обойтись и стрцпи. Тем более сдесь как раз копирование до нуль-терминатора.

                  тормозишь? в отличии от memcpy(), strcpy()/strncpy() останавливаются на нулевом символе.
                  Где сдесь это используется, в этом примере, конкретно?

                  Ща миня ,заминусуют...
                  Ответить
                  • цитирую: "ну это вопрос скорее к разрабам либы.)"

                    ты наехал на libc. ее никто сильно не любит, но она есть и работает.

                    > Ща миня ,заминусуют...

                    А то як жэ!
                    Ответить
                    • Кстати, а ведь он в чем-то прав...

                      Как ни парадоксально, но strcpy/strncpy/strcat/strncat юзабельны только для буферов, размер которых задан на этапе компиляции. В противном случае длину один хрен приходится хранить или замерять, и тогда memcpy работает быстрее, да и юзать его проще.
                      Ответить
                      • Дык при копировании все равно придется пробежать по всему буферу, в чем проблема параллельно проверять его на \0?
                        Ответить
                        • > в чем проблема параллельно проверять его на \0
                          В ненужности оного действа если мы и так знаем где он стоит. А мы знаем, т.к. длину строки или хранили или замерили.
                          Ответить
                          • Ты знаешь размер буфера, длину строки ты не знаешь. Второй раз замерять - это оверхед.
                            Ответить
                            • > Ты знаешь размер буфера, длину строки ты не знаешь.
                              Откуда я его знаю?

                              Он вбит намертво на этапе компиляции? Ну так я выше и написал, что в таких случаях эти функции имеют право на жизнь.

                              Я вычислил его на основе длины той строки, которую буду в него копировать (и, возможно, выделил под него память)? Ну и зачем я тогда буду замерять ее второй раз? Длина мне и так известна.

                              Мне похуй, что строка обрежется, лишь бы не было buffer overrun'ов и оверхеда на замер/хранение длины строк. Ну вот в этом случае strncpy прокатит.
                              Ответить
                        • копирование строк делается побайтово - потому что надо проверять на нолевой байт. это как минимум один if на скопированый байт + чтение байта + запись байта.

                          копирование блоков памяти известного размера делается по 4/8/16/больше байт подряд - потому что на ноль проверять не надо и размер заранее известен и нет шансов случайно выйты за пределы буффера.

                          на современных системах, с кэшами и прочими оптимизациями на уровне CPU, народ очень очень сильно изгаляется для того что бы достичь максимального бэндвидса шины памяти - именно для чего memcpy() и оптимизируется. типичная реализация memcpy() на порядок сложнее типичной реализации strcpy().
                          Ответить
                          • А длину строки ты откуда узнаешь? Прочитав побайтово исходную?
                            Ответить
                            • о, сорри.

                              я сравнивал memcpy() vs. strcpy(), а не strlen()+memcpy() vs. strcpy().

                              можно было бы как-нибудь бенчнуть, но мне лень. лично я все равно предпочитаю snprintf() для таких целей (потому что отдельно-стоящее копирование строк редко встречается).
                              Ответить
                            • > А длину строки ты откуда узнаешь?
                              Например храня ее рядом с самой строкой. Или как побочный эффект во время расчета длины буфера, в который будем копировать.

                              Т.е. strlen + malloc + memcpy vs strlen + malloc + strcpy.

                              Вот в этой ситуации strcpy всяко проиграет.

                              P.S. А strcat/strncat вообще Шмелиэль изобрел. Разве так трудно было вернуть указатель на терминатор, а не бесполезный указатель на начало буфера? ;)
                              Ответить
                              • >Например храня ее рядом с самой строкой.
                                Ну так strcpy для сишных строк сделали, а не для пасцалевских :)
                                Ответить
                                • >>Например храня ее рядом с самой строкой.
                                  А второй мой аргумент (как побочный эффект во время расчета длины буфера) опровергать не будем? :)
                                  Ответить
                                  • Я хз как там в сишке со строками. Получается, для копирования надо пройтись по тсроке 2 раза: 1 раз чтобы посчитать размер буфера и 2-й чтобы скопировать?
                                    Ответить
                                    • В Сишке строк нет. Это самый правильный ответ на твой вопрос
                                      Ответить
                                    • > 1 раз чтобы посчитать размер буфера и 2-й чтобы скопировать?
                                      Ну а куда деваться. Либо длина ограничена во время компиляции, либо ты получишь buffer overrun (strcpy без замера), либо у тебя обрежется конец строки (strncpy без замера), либо так как ты описал (strlen + malloc + mempy), либо ты хранишь длину аля пасцаль-строка.

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

                                      > В Сишке строк нет.
                                      Угу. Есть только строковые литералы. И несколько функций по обработке массивов как строк ;)
                                      Ответить
                                      • >Угу. Есть только строковые литералы. И несколько функций по обработке массивов как строк ;)

                                        не тру. А вообще строки нужны только на уровне view. как правило если в проге где то еще есть строки - она говно
                                        Ответить
                                      • PS Борманд, ты у нас хаскель любишь - что посоветуешь изучить из функциональщины? хаскель, ерланг или лисп?
                                        Ответить
                                        • > что посоветуешь изучить из функциональщины

                                          Ты же пишешь на шарпе, изучай F#, потом и до Haskell, глядишь, доберёшься.
                                          Ответить
                                          • да я бы с хаскеля начал, но пользы от него 0. ну разве что чсв прокачать
                                            Ответить
                                            • > пользы от него 0
                                              Польза от него в основном образовательная, море бесплатного фана и вынос мозга гарантированы. Я иногда пишу на нём небольшие одноразовые утилитки по работе. Собственно, по причине (пока ещё?) низкой потребности в Хаскеле я и предлагаю начать с F#.
                                              Ответить
          • показать все, что скрыто
            ~Клуб знакомств для геев~
                    Познакомлюсь с парнем
                      Сделаю миньет, подставлю попку парню кавказской внешности.
                      Прут наглые хуястые самцы, желательно с большим членом, так как  
                      очко сильно раздолблено. Могу принять сразу до 3-х парней.
                        Пишите [email protected]  /Тарас/
            Ответить
            • показать все, что скрыто
              ~Клуб знакомств для геев~
                   Познакомлюсь с парнем
                   Сделаю миньет, подставлю попку парню кавказской внешности.
                   Прут наглые хуястые самцы, желательно с большим членом, так как  
                   очко сильно раздолблено. Могу принять сразу до 3-х парней.
                      Пишите [email protected]  /Тарас/
              Ответить
              • показать все, что скрыто
                ~Клуб знакомств для геев~
                     Познакомлюсь с парнем
                     Сделаю миньет, подставлю попку парню кавказской внешности.
                     Прут наглые хуястые самцы, желательно с большим членом, так как  
                     очко сильно раздолблено. Могу принять сразу до 3-х парней.
                        Пишите [email protected]  /Тарас/
                Ответить
                • показать все, что скрыто
                  ~Клуб знакомств для геев~
                       Познакомлюсь с парнем
                       Сделаю миньет, подставлю попку парню кавказской внешности.
                       Прут наглые хуястые самцы, желательно с большим членом, так как  
                       очко сильно раздолблено. Могу принять сразу до 3-х парней.
                          Пишите [email protected]  /Тарас/
                  Ответить
                  • показать все, что скрыто
                    [color=blue]~Клуб знакомств для геев~[/color
                         Познакомлюсь с парнем
                         Сделаю миньет, подставлю попку парню кавказской внешности.
                         Прут наглые хуястые самцы, желательно с большим членом, так как  
                         очко сильно раздолблено. Могу принять сразу до 3-х парней.
                            Пишите [email protected]  /Тарас/
                    Ответить
                    • показать все, что скрыто
                      ~Клуб знакомств для геев~
                           Познакомлюсь с парнем
                           Сделаю миньет, подставлю попку парню кавказской внешности.
                           Прут наглые хуястые самцы, желательно с большим членом, так как  
                           очко сильно раздолблено. Могу принять сразу до 3-х парней.
                              Пишите [email protected]  /Тарас/
                      Ответить
      • Ммм, полутоновый.
        :D
        Ответить
    • n = strlen(pName);
      name = new char[n + 1];
      memcpy(name, pName, n+1);
      Ответить
    • Интересно, как бы написал этот код Царь?
      Ответить
      • name = new char[++(n=strlen(pName))],memset(name, 0, n),memcpy(name,pName, --n);
        Ответить
        • Страуструп не настолько безумен, чтобы так писать.
          Ответить
        • name=calloc((n=strlen(pName))+1,1),memcpy(name,pName,n);
          Ответить
          • Так вот зачем memcpy возвращает адрес буфера...
            Ответить
            • действительно, можно ещё на пару символов сократить
              n=strlen(pName),name=memcpy(calloc(n+1,1),pName,n);
              Ответить
              • Вот царский вариант (содержит UB):
                name=memcpy(malloc(n),pName,n=strlen(pName)+1)
                Ответить
                • > содержит UB
                  Я сначала тоже хотел похоже написать, но вспомнил, что на порядок вычисления аргументов полагаться нельзя.
                  Но ведь царь должен знать свой компилятор, поэтому волен свободно пользоваться ub по своему усмотрению.
                  Ответить
                  • Кстати, если переставить вычисление n внутрь malloc - начинает ломаться на -O0, но пашет на -O2. UB такой UB :)
                    Ответить
    • Любители. Настоящие кодеры используют стек
      char name = alloca(strlen(pName));
      Ответить

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