The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Рекурсивное использование asprintf, !*! datswd, 27-Сен-20, 09:14  [смотреть все]
Всех приветствую.

В GNU libc есть функция asprintf, которая делает то же самое, что и sprintf, но динамически выделяет память в результирующей переменной.

https://www.gnu.org/software/libc/manual/html_node/Dynamic-O...

Если сделать вот так:

asprintf(&a, "%s%s", a, "123");

В результате в переменной a окажется её содержимое дополненное строкой "123".

Вопрос в том, что происходит с точки зрения памяти? Память, изначально выделенная под a, утечет? Или там всё красиво и будет сделан realloc?

Заранее благодарен.

  • Рекурсивное использование asprintf, !*! pavel_simple., 22:11 , 27-Сен-20 (1)
    > Всех приветствую.
    > В GNU libc есть функция asprintf, которая делает то же самое, что
    > и sprintf, но динамически выделяет память в результирующей переменной.
    > https://www.gnu.org/software/libc/manual/html_node/Dynamic-O...
    > Если сделать вот так:
    > asprintf(&a, "%s%s", a, "123");
    > В результате в переменной a окажется её содержимое дополненное строкой "123".
    > Вопрос в том, что происходит с точки зрения памяти? Память, изначально выделенная
    > под a, утечет? Или там всё красиво и будет сделан realloc?
    > Заранее благодарен.

    https://elixir.bootlin.com/glibc/glibc-2.31/source/libio/vas...
    судя по ^^^ делает реаллок
    но проще ведь пупо проверить, не? в цикле?

    • Рекурсивное использование asprintf, !*! datswd, 08:07 , 03-Окт-20 (2)
      > но проще ведь пупо проверить, не? в цикле?

      Вот кстати да. Сделал вот такую штуку:

          int i = 1;
          char *p = NULL;
          char *c = "lalafalkjsdfhklj3h2iuhnklfsajbnlfiu2b    lkjdbslkabfqwilubfkldsajbfkljewqlkfdsa";
          int l = (int)strlen(c);
          while (1) {
      //        p = realloc(p, i * (l + 1) * sizeof(char));
      //        sprintf(p, "%s%s", i > 1 ? p :"", c);
              asprintf(&p, "%s%s", i > 1 ? p :"", c);


              i++;
              if(i >= 100000) {
                  printf("Free memory\n");
                  free(p);
                  p = NULL;
                  printf("Goto sleep\n");
                  sleep(5);
                  i = 1;
                  printf("Go on\n");
              }
          }

      Очень скоро после запуска оно сжирает всю память и ps -ax начинает говорить, что не может выполниться потому что нет памяти :))

      Если заменить asprintf на realloc + sprintf, то он вполне себе нормально работает.

      Ещё обратил внимание на то, что после первой итерации он память чистит, и pmap показывает, что в heap свободно, после всех последующих heap просто остается в максимальном значении. Это оптимизация так работает?

      • Рекурсивное использование asprintf, !*! datswd, 08:21 , 03-Окт-20 (3)
        >> но проще ведь пупо проверить, не? в цикле?
        > Вот кстати да. Сделал вот такую штуку:
        >     char *p = NULL;
        > p = NULL;

        Хммм.....
        Если заменить эти строчки на
        char *p = calloc(1, sizeof(char));
        p = calloc(1, sizeof(char));

        Тогда оно начинает абсолютно так же как и realloc+sprintf

        • Рекурсивное использование asprintf, !*! datswd, 20:34 , 13-Окт-20 (4)
          >>> но проще ведь пупо проверить, не? в цикле?
          >> Вот кстати да. Сделал вот такую штуку:
          >>     char *p = NULL;
          >> p = NULL;
          > Хммм.....
          > Если заменить эти строчки на
          > char *p = calloc(1, sizeof(char));
          > p = calloc(1, sizeof(char));
          > Тогда оно начинает абсолютно так же как и realloc+sprintf

          Ыыыы... :))
          Ошибочка. Вранья маленько написал. Даже с calloc asprintf работать так же как и realloc + sprintf не хочет.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру