Работа с возвращением строк C - PullRequest
8 голосов
/ 05 мая 2011

Что считается лучшей практикой при написании методов, возвращающих строки в C?

передача в буфер и размер:

void example_m_a(type_a a,char * buff,size_t buff_size)

или создание и возврат строки правильного размера:

char * example_m_b(type_a a)

P.S. что вы думаете о возвращении буфера ptr, чтобы позволить стиль назначения и вызовы вложенных функций, т.е.

char * example_m_a(type_a a,char * buff,size_t buff_size)
{
...
return buff;
}

Ответы [ 5 ]

5 голосов
/ 05 мая 2011

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

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

3 голосов
/ 05 мая 2011

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

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

1 голос
/ 05 мая 2011

Другая альтернатива передаче буфера и стиля размера с использованием кода возврата:

size_t example_m_a(type_a a,char * buff,size_t buff_size)

Нулевой код возврата указывает, что буфер вызывающего абонента был подходящим и был заполнен.

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

1 голос
/ 05 мая 2011

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

0 голосов
/ 05 мая 2011

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

Единственный раз, когда я видел функцию, возвращающую выделенный буфер, это API libxml для генерации XML-текста из xmlDoc.

...