выделить память для проблемы sprintf? - PullRequest
2 голосов
/ 29 декабря 2010

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

char *Data = malloc(1024*1024);  //???????
sprintf(Data, "%s %s", Data1, Data2);

Время от времени размер данных 1 и данных 2 варьируется .... от очень очень длинных до очень маленьких мне было интересно, есть ли возможность использовать sprintf без выделения памяти или чего-то еще, поскольку выделенная память может быть когда-то небольшой ..

спасибо

Ответы [ 6 ]

6 голосов
/ 29 декабря 2010

Многие библиотеки времени выполнения C (например, GNU glibc и FreeBSD (а также NetBSD, OpenBSD и OS X) libc) предоставляют asprintf, который объединяет malloc и sprintf в один вызов.

char *Data = NULL;
asprintf(&data, "%s %s", Data1, Data2);

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

5 голосов
/ 29 декабря 2010

Поскольку data1 и data2 кажутся строками, просто используйте strlen () и выделите только тот объем памяти, который вам действительно нужен.

char *data = malloc(sizeof(char) * (strlen(data1) + strlen(data2) + 1));
4 голосов
/ 29 декабря 2010

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

Обратите внимание, что MSVC не имеет snprintf(), но включает в себя аналогичный _snprintf(). Однако эта функция имеет как минимум 2 отличия от стандартных:

  • это может оставить результат без изменений
  • он не скажет вам, какой размер буфера вам нужен, если он усекается

Если вы используете MSVC, вы можете рассмотреть возможность использования реализации Holger Weiss snprintf() (которая имеет либеральную лицензию).

1 голос
/ 29 декабря 2010

Не возможно. Вы всегда должны выделять буфер, используемый sprintf / printf

0 голосов
/ 01 января 2011

Почему бы не использовать функции strlen для размеров строк?

char *buf = malloc(strlen(Data1) + strlen(Data2) + 2); // 2 for space and \0
sprintf(buf, "%s %s", Data1, Data2);

Это решает проблему, когда вам нужно выяснить размер данных Data1 и Data2 во время выполнения.

0 голосов
/ 29 декабря 2010

Короткий ответ - нет.

... Но вам не нужно выделять каждый раз, когда ваш код запускается. В зависимости от того, является ли ваша программа многопоточной, как часто будет выполняться этот раздел кода и насколько велика максимально возможная строка, которую вы ожидаете, вам, вероятно, лучше выделить один буфер «максимально возможного размера» один раз. и использовать безопасную версию sprintf, такую ​​как snprintf, чтобы заполнить ее. (Охраняет от переполнения). Или вы можете условно перераспределить буфер, если требуемый размер превышает текущий размер буфера.

Например, если вы используете C ++ и ваш код выше живет внутри метода, вы можете изменить строку размещения данных на:

static char *Data = malloc(1024*1024);

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

Если вы используете C, то ваш буфер может быть глобальным (я не фанат этого), или вы можете передать указатель на локально ограниченный буфер данных. Я уверен, что у настоящих программистов на Си есть лучшие предложения о том, как делать такие вещи.

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

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