При работе с C API используйте символьные массивы или строки и конвертируйте при необходимости? - PullRequest
4 голосов
/ 07 февраля 2012

Я работаю с C API, и многие функции принимают аргументы, которые являются символьными массивами. Я слышал, что использование массивов char теперь не одобряется. Но с другой стороны, использование c_str() для преобразования строки в массив char снова и снова кажется расточительным.

Есть ли причины делать это в одну сторону против другой?

Ответы [ 5 ]

10 голосов
/ 07 февраля 2012

Вызов c_str() вполне может быть встроенным - он очень мал с точки зрения требуемого кода.Я бы использовал std::string, если это единственное, что вас сдерживает.

Конечно, если вы очень волнуетесь, применяется этот стандартный совет:

  1. Профилируйте его
  2. Прочтите сборку

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

2 голосов
/ 07 февраля 2012

Это зависит от того, что вы делаете, и что делают функции интерфейса.С одной стороны, я не думаю, что кто-то порекомендует преобразовать строковый литерал в std::string, просто чтобы вы могли вызвать c_str для него.С другой стороны: любой код, строящий строки динамически, должен использовать std::string.Такие функции, как strcpy и strcat, являются приглашением к переполнению буфера.Между двумя это зависит.Я бы сказал, что критерии должны быть простыми и безопасными: в любое время проще или безопаснее использовать std::string, используйте std::string.Пока то, что вы делаете, не требует динамического выделения char[], и такие вещи, как operator+ в строках, не будут использоваться, вы можете использовать char[].

2 голосов
/ 07 февраля 2012

Как уже упоминалось, c_str() будет встроено. Но то, что не было упомянуто, но то, что я считаю одним из наиболее важных аспектов вашего вопроса, это то, что std::string следует принципам RAII. При использовании std::string вам не нужно помнить об освобождении строки или беспокоиться о безопасности исключений. Просто убедитесь, что каждый экземпляр std::string не уничтожен до тех пор, пока код C не будет выполнен со строкой. Это может быть особенно проблемой, если std::string является временным, созданным компилятором.

Если ваша функция C записывает обратно строку, вы можете использовать vector<char> и установить размер в соответствии с желаемым размером буфера. Таким образом, вы все равно будете следовать принципам C ++ RAII.

2 голосов
/ 07 февраля 2012

Большинство реализаций std::string, вероятно, в любом случае сохраняют фактическую строку как строку C, поэтому функция c_str - это просто встроенная функция, которая возвращает указатель. В общем, я бы сказал, что правильный путь - это std::string.

Конечно, если строка предназначена для изменения вызываемой функцией, тогда вы не можете использовать подход std::string. Вместо этого вам придется сделать копию в свой собственный буфер перед вызовом функции, и в этом случае использование массивов может быть правильным способом.

1 голос
/ 07 февраля 2012

Существует очень простая причина использовать string: , это работает .

Работа с C-струнами - это боль:

  • ручное выделение и освобождение памяти подвержено ошибкам
  • сам интерфейс предрасположен к ошибкам (обычное отсутствие символьного завершения, ошибки "за одним" и переполнения буфера являются общими)
  • операции неэффективны (strlen, strcpy и strcat), потому что длина должна пересчитываться каждый раз

Я действительно не вижу веской причины для когда-либо работы с C-строками.

Это такая боль, что многие платформы предоставили свои собственные специфические операции и что было предложено несколько «лучших строк» ​​(о, радость наличия нескольких стандартов).

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