В чем разница между строковым массивом и массивом символов, объявленным с помощью указателя? [Дубликат]

74
задан jww 8 February 2015 в 22:23
поделиться

12 ответов

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

Я использую std :: string / wstring для более или менее всего, что является фактическим текстом. char * полезен для других типов данных, хотя вы можете быть уверены, что он будет освобожден, как и должен. В противном случае std :: vector - путь.

Вероятно, есть исключения для всего этого.

52
ответ дан Skurmedel 4 September 2018 в 07:38
поделиться

Моя точка зрения:

  • Никогда не используйте char *, если вы не вызываете код «C».
  • Всегда используйте std :: string: это проще , он более дружелюбен, он оптимизирован, он стандартен, это предотвратит появление ошибок, проверено и проверено на работоспособность.
52
ответ дан Gal Goldman 4 September 2018 в 07:38
поделиться

Один раз, когда вы ДОЛЖНЫ использовать char*, а не std::string, вам понадобятся статические строковые константы. Причина этого в том, что у вас нет никакого контроля над модулями заказа, инициализируйте их статические переменные, а другой глобальный объект из другого модуля может ссылаться на вашу строку перед ее инициализацией. http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Static_and_Global_Variables

std::string профи:

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

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

8
ответ дан HugoTeixeira 4 September 2018 в 07:38
поделиться

Вы должны рассмотреть возможность использования char* в следующих случаях:

  • Этот массив будет передан в параметре.
  • Вы заранее знаете максимальный размер вашего array (вы знаете это ИЛИ вы его навязываете).
  • Вы не будете делать никаких преобразований в этом массиве.

На самом деле, в C ++, char* часто используются для фиксированного маленького слова, в качестве параметров, имени файла и т. д. ...

8
ответ дан Jérôme 4 September 2018 в 07:38
поделиться

Если вы хотите использовать библиотеки C, вам придется иметь дело с C-строками. То же самое относится, если вы хотите выставить свой API на C.

2
ответ дан n0rd 4 September 2018 в 07:38
поделиться

Когда использовать строки c ++ std :: string:

  • , в целом, более безопасны, чем char *. Обычно, когда вы делаете вещи с char *, вам нужно проверить, что делать Конечно, все правильно, в строковом классе все это делается для вас.
  • Обычно, когда вы используете char *, вам нужно освободить выделенную память, вам не нужно делать это с помощью строки, поскольку он будет освобождать свой внутренний буфер при уничтожении.
  • Строки хорошо работают с c ++ stringstream, форматированный IO очень прост.

Когда использовать char *

  • Использование char * дает вам больше контроля над тем, что происходит «позади» сцен, что означает, что вы можете настроить производительность, если вам нужно.
5
ответ дан Nathan Ridley 4 September 2018 в 07:38
поделиться

Использовать (const) char * в качестве параметров, если вы пишете библиотеку. Строковые реализации различаются между разными компиляторами.

3
ответ дан Nemanja Trifunovic 4 September 2018 в 07:38
поделиться

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

-1
ответ дан piotr 4 September 2018 в 07:38
поделиться

, если вы используете массив символов в виде текста и т. д., используйте std :: string более гибким и простым в использовании. Если вы используете его для чего-то еще, например для хранения данных? использовать массивы (предпочитают векторы)

1
ответ дан RvdK 4 September 2018 в 07:38
поделиться

Даже когда производительность имеет решающее значение, вам лучше использовать vector<char> - она ​​позволяет заранее распределить память (метод reserve ()) и поможет вам избежать утечек памяти. Использование vector :: operator [] приводит к накладным расходам, но вы всегда можете извлечь адрес буфера и точно его индексировать, если это был char *.

1
ответ дан sharptooth 4 September 2018 в 07:38
поделиться

Использование исходной строки

Да, иногда вы действительно можете это сделать. При использовании const char *, массивов символов, выделенных в стеке и строковых литералах, вы можете сделать это таким образом, что распределение памяти вообще отсутствует.

Написание такого кода требует часто большего мышления и заботы, чем использование строки или вектор, но с надлежащими методами это можно сделать. При правильных методах код может быть безопасным, но вам всегда нужно убедиться, что при копировании на char [] у вас есть какие-то гарантии на длину скопированной строки, или вы грамотно проверяете и обрабатываете негабаритные строки.

Как шаблоны могут помочь писать безопасные буферы символов

Что касается безопасности шаров char [], шаблоны могут помочь , поскольку они могут создать инкапсуляцию для обработки размера буфера для вас. Такие шаблоны, например, реализованы, например. от Microsoft, чтобы обеспечить безопасную замену для strcpy. Пример здесь извлекается из моего собственного кода, у реального кода гораздо больше методов, но этого должно быть достаточно, чтобы передать основную идею:

template <int Size>
class BString
{
  char _data[Size];

  public:
  BString()
  {
    _data[0]=0;
    // note: last character will always stay zero
    // if not, overflow occurred
    // all constructors should contain last element initialization
    // so that it can be verified during destruction
    _data[Size-1]=0;
  }
  const BString &operator = (const char *src)
  {
    strncpy(_data,src,Size-1);
    return *this;
  }

  operator const char *() const {return _data;}
};

//! overloads that make conversion of C code easier 
template <int Size>
inline const BString<Size> & strcpy(BString<Size> &dst, const char *src)
{
  return dst = src;
}
13
ответ дан Suma 4 September 2018 в 07:38
поделиться

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

Также стоит отметить, что итераторы std :: string довольно часто отображают указатели в базовый массив. Таким образом, любой алгоритм, который вы разрабатываете поверх итераторов, по существу идентичен тому же алгоритму в верхней части char * с точки зрения производительности.

Вещи, которые следует учитывать, например, operator[] - большинство реализаций STL не выполняют проверку границ и должны перевести это на ту же операцию в базовый массив символов. AFAIK STLPort может дополнительно выполнить проверку границ, и в этот момент этот оператор будет немного медленнее.

Итак, что делает использование std :: string для вас? Это освобождает вас от ручного управления памятью; изменение размера массива становится проще, и вам обычно приходится меньше думать о освобождении памяти.

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

2
ответ дан user 4 September 2018 в 07:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: