LINUX.ORG.RU

Помогите разобраться с malloc СИ

 ,


0

3

Здравствуйте.

Есть функция в которой есть две переменные для массивов - buff и trans_rate:

void rate_coin(char *coin)
 {
    FILE *rat_coi;
    char *buff = (char*) malloc(128 * sizeof(char));
    snprintf(buff, (int)strlen(coin) + 59, "%s%s%s", "curl https://api.coinmarketcap.com/v1/ticker/", coin, "/ 2>/dev/null"); 
    printf("Coinmarketcap: %s\n", buff);
    rat_coi = popen(buff, "r"); 
    if(rat_coi == NULL) error_log("rat_coi!");

    char trans_rate[128] = {0,};
    //char *trans_rate = (char*) malloc(128 * sizeof(char));
    int count = 0;
    strcat(trans_rate, "RATE COIN\n");
    memset(buff, 0, 128);
    while(fgets(buff, 126, rat_coi) != NULL)
     {
       count++;
       if(count > 8) break;
       if(count == 4 || count == 7 || count == 8)
        {
          char *pch = strtok(buff, " ,\"");
          while(pch != NULL)
           {
             char *ptr = strchr(pch, ':');
             if(ptr!=NULL) *ptr = ' ';
             strcat(trans_rate, pch);
             pch = strtok(NULL, " ,\"");
           }
        }
     }

    trans_rate[strlen(trans_rate) - 1] = 0;
    SendMessage(glob_chat_id, trans_rate);
    free(buff);
    printf("%s\n\n", trans_rate);
    //free(trans_rate);
 }

Для переменной buff делаю malloc, использую её в функции snprintf(buff, ...). После этого очищаю buff с помощью memset(buff,...), использую её же в функции while(fgets(buff,...) и в конце освобождаю память - free(buff);.

Для переменной trans_rate выделяю нужное кол-во байт и использую её.

Всё работает хорошо.

Если же для переменной trans_rate тоже делать malloc (строчка закомментирована) вместо char trans_rate[128] = {0,};, то прога начинает вести себя непредсказуемо, как будто перекрываются массивы (в printf попадают непонятные символы):

h�"�WRATE COIN

Объясните пожалуйста, почему в данном случае для buff malloc работает, а для trans_rate нет?


Ответ на: комментарий от Virtuos86

в Си сложно писать http-запросы или нет библиотек для этого?

Есть библиотеки. Один раз пишешь, потом используешь. Естественно, каждый раз с нуля сниппеты не делаются.

какой прок от производительности Си?

При чем здесь производительность? Си — простой и понятный язык, на котором можно все, что угодно написать, а через 20 лет открыть исходник, и все будет ясно. Чего о всяких говнах вроде пхытона/го/пыхпыха и прочего раста совсем не скажешь!!!

И не надо теплое с мягким сравнивать. Ты похож на ламеров, которые спрашивают у меня: «зачем тебе гента? Что ты там оптимизируешь? Ведь выгода в оптимизации от силы 1-2%!» Им, бедолагам, не понять, что проще и удобней дистрибутива просто нет!

На питоне этот код напишется левой пяткой и уже работал бы.

Тяп-ляп и в продакшн? Говнотяпы вроде тебя, надеюсь, вымрут скоро!

anonymous
()
Ответ на: комментарий от Virtuos86

Для какой железяки вы пишете прошивку

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

Пишу на СИ потому-что нравится морочится. Плюсы планирую изучать в будущем, когда постигну (видимо не скоро) СИ.

Делаю всё для себя, с работой это никак не связано.

Писать на Питоне не хочу, сервер в пять строк, ну куда это годится))).

stD
() автор топика
Ответ на: комментарий от anonymous

Тебя мама не учила не отвечать на вопросы, которые заданы не тебе? А зря.

На питоне этот код напишется левой пяткой и уже работал бы.

Тяп-ляп и в продакшн? Говнотяпы вроде тебя, надеюсь, вымрут скоро!

Не тяп-ляп, а легко и ненапряжно. Разумные люди выбирают инструменты, исходя из задачи. Питон/перл/пых — всё ЯП для обработки текста прежде всего, а веб у нас пока гипертекстовый в-основном, чуешь? Поэтому на питоне люди крутят текстовые данные, как хотят, а здесь бедолага в трёх соснах плутает, бодаясь с массивами чаров, словно это нормальные строки, ага, в 2017 году.

Virtuos86 ★★★★★
()
Ответ на: комментарий от stD

Писать на Питоне не хочу, сервер в пять строк, ну куда это годится))).

Вот-вот. Но в своё личное свободное время можно и на асме писать, никто не спорит :-).

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

бодаясь с массивами чаров

)))

Возьму на себя смелость задать ещё один ламерский вопрос.

Что из представленного выполнится быстрее?

void rate_coin(char *coin)
 {
    char *buff = (char*)malloc(128 * sizeof(char));
    ...
void rate_coin(char *coin)
 {
    char buff[128] = {0,};
    ...
char buff[128] = {0,};

void rate_coin(char *coin)
 {
    memset(buff, 0, 128);
    ...
stD
() автор топика
Ответ на: комментарий от Sorcerer

Вариант 4 будет быстрее:

То есть выделяется статистический массив и зануляется первый байт, а на остальные не важны?

А во сколько, примерно, раз дольше будет выполняться малок?

stD
() автор топика
Ответ на: комментарий от stD

Я не знаю Си. Но осуждаю, как Пастернака. И по подобным тредам вижу, что писать на нём неоптимальный код — проще простого.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Фигасе, «легко и ненапряжно»! Это с дерьмосинтаксисом-то пхытона? На сях это как раз будет легко и ненапряжно.

для обработки текста прежде всего

Там обработки текста обычно меньше 1%, все остальное — обработка данных, БД и т.п. И сишный демон для этого лучше всего подходит.

А бедолага плутает, потому что даже K&R не прочел хотя бы раза три!

anonymous
()
Ответ на: комментарий от anonymous

Пять(!) вариантов написать инстанцирование массива. Очень легко, наверное, научиться выбирать оптимальный). На чем-то вроде Rust ТС просто написал бы let mut buff = [char; 128usize];

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от stD

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

из трёх предложенных самый быстрый третий но лучше всёж второй ибо не загромождает глобальное пространство имён во первых, и вовторых держет(и затерает нулями перед использованием) на стеке то чему и место на стеке.

но тут вопрос скорости исполнения как просьба дать черпак по больше когда дают в тесте на нормальность вычерпать ванну ложкой.

вроде как обычно принято оптимизировать не всё подряд а «горячие участки» которые видны невооружённым глазом и/или всяким пролифировщиком и/или анализатором кода ( ну там внутренности вложенных в циклы циклов и прочие «рекурскии»)

зы. ну блин полистай K&R - не шучу - лучше на английском и лучше самое первое издание ибо оно для взрослых.

anonymous
()
Ответ на: комментарий от stD

сервер в пять строк, ну куда это годится)))

ты мне монитор жиром заляпал.

anonymous
()

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

AUX ★★★★
()
Ответ на: комментарий от stD

Если ты хочешь быстрее, то начни оптимизацию с замены popen, на libcurl.

malloc это сискол и он будет медленнее. Все остальные расстановки memset и прочего уже зависят от компилятора. С -O3 он может сделать невероятные вещи.

xpahos ★★★★★
()

malloc() не инициализирует память (не забивает 0).

в приведённом случает это единственная разница и единственная причина (непонятного) поведения

хотя в коде более чем вероятно есть ошибки не связанные с malloc или статик :-)

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Над чем? malloc это обертка над sbrk/brk/mmap, пока память не будет освобождена где либо еще, malloc продолжит просить ядро выделить памяти. Да, существуют аллокаторы, которые заранее собирают себе маленький слаб, но не все это делают. Остальные объявления будут лежать в bss и при загрузке бинарника проинициализированы нулями.

xpahos ★★★★★
()
Ответ на: комментарий от Virtuos86

Есть целые web-движки на ассемблере i(4)86, развлекается народ.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Virtuos86

Пять(!) вариантов написать инстанцирование массива.

Я не знаю Си.

Оно и заметно.

И по подобным тредам вижу, что писать на нём неоптимальный код — проще простого.

Говнокод проще простого писать на любом языке.

Очень легко, наверное, научиться выбирать оптимальный). На чем-то вроде Rust ТС просто написал бы

Лол. У меня жир потёк из монитора.

Deleted
()
Ответ на: комментарий от Deleted

Пять(!) вариантов написать инстанцирование массива.
Я не знаю Си.

Оно и заметно.

Потрудись заметить и Пять(!) вариантов написать инстанцирование массива. Такое обилие обусловлено моим незнанием Си? Или эти примеры делают разные вещи, а не одно и то же разными способами?

И по подобным тредам вижу, что писать на нём неоптимальный код — проще простого.

Говнокод проще простого писать на любом языке.

Какие из трёх вариантов ТС являются говнокодом (если допустить, что два решения от профессионалов не-говнокод)? Почему ТС, используя Си, не знает, что предлагает очевидный говнокод? Или говнокод неочевидный?

Virtuos86 ★★★★★
()
Ответ на: комментарий от Deleted

пятизвёздочные эксперты в тред набежали

ох уж эти комплексы юзеров с маленькой пиписькой^W^W^W без звёзд

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Или эти примеры делают разные вещи, а не одно и то же разными способами?

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

Почему ТС, используя Си, не знает, что предлагает очевидный говнокод? Или говнокод неочевидный?

ТС не знает Си и предлагает варианты методом перебора.

Deleted
()
Ответ на: комментарий от Deleted

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

Это итак одно и то же. Но ты не переживай.

rustonelove
()
Ответ на: комментарий от Deleted

Не прибедняйся. Суммарный стаж твоих двух акков примерно равен моему, и в бытность geekless'ом срал ты предостаточно. Потом, может, приоритеты и поменялись, но это не повод из себя праведника строить.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Я вообще-то не к тебе обращался в комменте про звёзды.

Информация о пользователе xpahos

Первая созданная тема: 10.12.2005 16:57:50

Первый комментарий: 10.12.2005 23:01:30

Deleted
()
Ответ на: комментарий от Deleted

Или эти примеры делают разные вещи, а не одно и то же разными способами?

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

Стек, куча и питон? О чём ты? Перерой всю доку по питону, не найдёшь никакого упоминания стека, ну может быть, только если начнешь ковыряться в байткоде, тогда придётся разбираться, как работает стековая VM питона. Ты, когда на рубине писал, тоже по стеку и куче шарился?)

Правда всё равно не понятно, как ты умудряешься в этом случае писать на путоне. Ну или на чем там...

Ну да, ну да. Куда нам до сишников.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

только если начнешь ковыряться в байткоде, тогда придётся разбираться, как работает стековая VM питона.

А чтобы писать производительный код, это таки придётся.

Плюс еще и обмазываться вызовами сишных библиотек. Которые сами родятся в репах, потому что настоящему питонисту учить Си западло.

Ты, когда на рубине писал, тоже по стеку и куче шарился?)

Что значит «писал»?

Deleted
()
Ответ на: комментарий от Virtuos86

Стек, куча и питон? О чём ты? Перерой всю доку по питону, не найдёшь никакого упоминания стека

И про области видимости, вероятно, тоже упоминания не найдёшь. Тяжко, понимаю.

Deleted
()
Ответ на: комментарий от anonymous

Учите матчасть.

Ваша конструкция инициализирует весь массив нулями, моя - только его первый байт.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

Вариант 4 будет быстрее:

Ну раз уж тут пошли звездами мериться, то придётся соотвествовать уровню.. :)

Третий вариант ( Помогите разобраться с malloc СИ (комментарий) ) будет быстрее, если там не гигабайты, так как 128 байт обнулить системе не долго и вероятность что этот кусок попадёт в ту же страницу BSS, что и остальной BSS этого процесса. А вот когда кушается стек, то вполне может оказаться, что страница памяти под это пожирание стека ещё системой не выделена, и ваше обнуление первого элемента может вылиться в переключение из user-level в 0-level, свопирование и обратно.

vodz ★★★★★
()
Ответ на: комментарий от Virtuos86

Я не знаю Си

А какого хрена вообще в программистские темы лезешь, если к программированию относишься так же, как доярка к президенству?

anonymous
()
Ответ на: комментарий от vodz

Могу согласиться, если эта функция рекурсивная, и стек интенсивно пожирается. Если нет, то 128 байт весьма вероятно окажутся уже доступны, причём они могут быть не просто доступны, а и вероятно будут закешированы.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

Могу согласиться, если эта функция рекурсивная, и стек интенсивно пожирается.

Ну как это может быть рекурсивное пожирание, если мы сравниваем со статическим буфером? ;)

Если нет, то 128 байт весьма вероятно окажутся уже доступны

Да я про то, что:

char buf[128]; int main(void) { return 0; }
size a.out 
   text    data     bss     dec     hex filename
   1476     528     160    2164     874 a.out
128 < 160 < 4096. То есть BSS у процесса есть (в startup-коде) и укладывается в одну страницу. А вот сколько будет скушано стека неизвестно, вероятность что уйдёт за границу текущей предоставленной памяти не большая, но есть.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Ну как это может быть рекурсивное пожирание, если мы сравниваем со статическим буфером? ;)

Действительно. :)

Да я про то

Я это понял. Можно, конечно, подобрать такие хитрые условия, когда вариант с инициализацией одного байта на стеке окажется медленнее инициализации 128 статических байт, но утверждать, что это точно будет медленней, я бы не стал. :) А так - можно и обратный пример придумать, - наша функция в большой библиотеке, в эту библиотеку никто не лез, страницы с её данными ещё не загружены. И тогда будут дикие тормоза. :)

Sorcerer ★★★★★
()
Ответ на: комментарий от vodz

Третий вариант ( Помогите разобраться с malloc СИ (комментарий) ) будет быстрее, если там не гигабайты,

Опять я слышу эти потуги из помойки.

так как 128 байт обнулить системе не долго

Ога, 128 байт, системе, мемсетом.

и вероятность что этот кусок попадёт в ту же страницу BSS, что и остальной BSS этого процесса.

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

Я даже не буду спрашивать то, что такое «страница BSS» - я ответа не получу.

А вот когда кушается стек, то вполне может оказаться, что страница памяти под это пожирание стека ещё системой не выделена

Ога, страницы, не выделена. Пожирание стека. Пожирание.

и ваше обнуление первого элемента может вылиться в переключение из user-level в 0-level, свопирование и обратно.

0-level, ога. Свопирование. И обратно.

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

Как максимум эти потуги можно привязать только к тому, что «там уже может», а «тут не может», но это абсолютно не имеет смысла - ведь что там, что там оно может в равных степенях, даже наоборот - в стеке шанс на это меньше.

rustonelove
()
Ответ на: комментарий от anonymous

Я не знаю Си

А какого хрена вообще в программистские темы лезешь, если к программированию относишься так же, как доярка к президенству?

Ути-пути, какой жирненький. Даже у «царя» ЧСВ сишника не настолько затуманивает разум, чтобы утверждать, что программирование == Си. Не под микроконтроллеры пишешь? Поговаривают, эти ребята в конец упоротые.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Sorcerer

Можно, конечно, подобрать такие хитрые условия

Ламерка ты можешь помножить на ноль одним словом - mt-safe и ламерок улетит на помойку, где ему самое место.

rustonelove
()
Ответ на: комментарий от rustonelove

Мы тут о сферических конях в вакууме рассуждаем, так что всё в порядке. Понятно, что такой код, - инициализацию статического вспомогательного массива нулями для последующего printf туда, - всерьёз никто не воспринимает.

Sorcerer ★★★★★
()
Ответ на: комментарий от Sorcerer

Можно, конечно, подобрать такие хитрые условия, когда вариант с инициализацией одного байта на стеке окажется медленнее инициализации 128 статических байт

Нет никакой специальной инициализации 128 байт. Будет выделена страница, которая и будет проинициализирована нулями, так как это BSS.

vodz ★★★★★
()
Ответ на: комментарий от Virtuos86

Потрудись заметить и Пять(!) вариантов написать инстанцирование массива. Такое обилие обусловлено моим незнанием Си? Или эти примеры делают разные вещи, а не одно и то же разными способами?

Никаких пяти вариантов там нет. Вариант один, только он определяется в разных контекстах(скорее всего это есть и в твоём расте) и с инициализацией/без.

Два варианта инициализации есть потому, что пацанам надо передать пустую строку - которая является первым нулевым символом. И сколько и что там будет далее - ни на что уже не влияет.

Какие из трёх вариантов ТС являются говнокодом

Никакие. Просто ТС не понимает что такое {}, да и 99% ламерков тут то же.

Почему ТС, используя Си, не знает, что предлагает очевидный говнокод? Или говнокод неочевидный?

Потому что это никакого отношения к Си не имеет. Это вопросы выбора и его целесообразности, которые есть везде - даже на твоём пхп.

Всё то же самое есть и в жабке и в расте.

rustonelove
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.