Целое число в строку в C без предварительно выделенного массива char - PullRequest
0 голосов
/ 30 сентября 2010

Пожалуйста, посмотрите на следующий код, который просто преобразует беззнаковое целое в строку (могут быть некоторые необработанные случаи, но это не мой вопрос), выделяя массив char в куче и возвращая его, оставляя пользователю ответственность освободите его после использования. Можете ли вы объяснить мне, почему такая функция (и другие подобные) не существует в стандартной библиотеке C? Да, printf("%s\n", itos(5)) - это утечка памяти, но этот шаблон программирования уже используется и считается хорошей практикой [1]. IMO, если бы такие функции существовали с момента появления C, у нас было бы мало утечек памяти больше, но тонн переполнений буфера меньше!

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

char* itos(unsigned int value)
{
    int string_l = (value == 0) ? 1 : (int)log10(value) + 1;
    char *string = malloc((string_l + 1) * sizeof(char));
    int residual = value;
    int it;
    for (it = string_l - 1; it >= 0; it--) {
        int digit;
        digit = residual % 10;
        residual = residual / 10;
        string[it] = '0' + digit;
    }
    string[string_l] = '\0';
    return string;
}

int main(void)
{
    char* string = itos(534534345);
    printf("%s\n", string);
    free(string);
    return 0;
}

[1] http://www.opengroup.org/onlinepubs/009695399/functions/getaddrinfo.html

EDIT:

ответ Хабби:

char *string;
asprintf(&string, "%d", 155);
printf("%s\n", string);
free(string);

Ответы [ 3 ]

1 голос
/ 03 октября 2010

получается, что asprintf - это то, что вам нужно:)

1 голос
/ 30 сентября 2010

На мой взгляд, управление памятью зависит от абонента, а не от абонента. Например, когда я не использую стандартную реализацию malloc() в своей программе, я очень расстроюсь из-за необходимости найти и вызвать соответствующий free(), в результате я бы не стал использовать такую ​​функцию.

Редактировать: Ваш getaddrinfo() пример идеален, они предоставляют и getaddrinfo(), и freeaddrinfo(), это единственный способ убедиться, что я звоню вправо free().

0 голосов
/ 30 сентября 2010

Программирование развивалось с момента его создания - это просто то, чего не было с рассвета C, но с тех пор оно развивалось и в других языках. Мне особенно нравится способ, которым target-c обрабатывает это, возвращая строковый объект, который был автоматически освобожден (то есть он будет автоматически освобожден позже, после того, как объект вышел из области видимости). Вы можете реализовать нечто подобное в C, если хотите:

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

Еще один способ добиться того же, но позволяющий вам использовать системные функции, которые используют malloc для выделения памяти:

  1. вне вашего основного цикла создайте список (изначально пустой) объектов 'to-be-free'
  2. написать функцию с именем «autofree», которая добавляет указатели в список и возвращает указатель
  3. всякий раз, когда вам нужно использовать его следующим образом: printf("%s\n", autofree(itos(5)));
  4. каждый раз вокруг вашего основного цикла, освобождать все указатели в списке и очищать список

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...