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 нет?


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

Эдик, ну включи голову уже. У тебя может быть реализация libc вообще без ядра. Эмбедд, голое железо.

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

Более того, в системах реального времени возможен malloc() с гарантированным константным временем исполнения. Страницы под кучу мапятся на этапе инициализации, а при выделении памяти из кучи поиск осуществляется по битовой карте корзин заведомо подходящего размера. O() = const

Вот тебе и «вызовы ядра».

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

О функции, которая в линуксе завершается сисколлами!

Кстати, на микроконтроллерах я такой фигней не страдаю, и malloc'и-шмаллоки не использую, как и ртоси — не нужно оно там!

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

крайне редкоотвечаю анонимусам, но это тот случай:

О функции, которая в линуксе завершается сисколлами!

вот ведь безграмотный долб@#п ;-) читайте уже матчасть...

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

Ты хочешь сказать, что mmap — не сисколл? А оперативку щедрой рукой Аллах пользователю по malloc отдает?

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

Мы говорим о функции.

Интересно, а как с константным временем для malloc при фрагментации «кучи»? Не делать дефрагментацию? Кстати, если сисколы увязать с RT, то как раз malloc=sbrk и с фикцией для free() наоборот гораздо занятный вариант — памяти выделится всё доступное системе за константное время...

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

Интересно, а как с константным временем для malloc при фрагментации «кучи»? Не делать дефрагментацию?

Что такое «дефрагментация» кучи? Она невозможна физически.

Если имеется в виду слияние соседних свободных блоков, то достаточно на каждом free() пытаться слить с одним предыдущим и одним следующим блоком. Это тоже O(1).

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

Что такое «дефрагментация» кучи? Она невозможна физически.

Если «физически», то это sbrk(-размер)/munmap()

Если имеется в виду слияние соседних свободных блоков, то достаточно на каждом free() пытаться слить с одним предыдущим и одним следующим блоком. Это тоже O(1).

Ну это ж не панацея. Выделили миллион по 16 байт, всё освободили, а потом запросили 64 байта... И обломаетесь.

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

Ну это ж не панацея. Выделили миллион по 16 байт, всё освободили, а потом запросили 64 байта... И обломаетесь.

Если выделили, а потом всё освободили, то никакой фрагментации и не будет. Будет свободная область на 1 000 000 * (16 + оверхед) байт.

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

Если выделили, а потом всё освободили, то никакой фрагментации и не будет.

Не не. Это только если освобождать ровно в обратной последовательности к запросам на выделение. Если ровно с начала (а так ведь всегда легче), то будет ровно как сказал, будут блоки по 48 байт.

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

Выделено:

1 2 3 4 5 6 7 8 9
A A A A A A A A A

Освобождаем:

1 2 3 4 5 6 7 8 9
F A A A A A A A A
^
+-- 1 свободный  блок 


1 2 3 4 5 6 7 8 9
F F A A A A A A A
  ^
  +-- сливаем с предыдущим, снова получился 1 свободный блок

1 2 3 4 5 6 7 8 9
F F F A A A A A A
    ^
    +-- сливаем с предыдущим, снова получился 1 свободный блок

.
.
.

1 2 3 4 5 6 7 8 9
F F F F F F F F F

1 большой свободный блок

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

А, я вспомнил, почему у меня так не получалось. Адрес «вперед» получить просто, размер блока то так и так известен, а назад уже сложнее.

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