C ++ way
std::string name = "testing";
std::string nameC = name;
В C ++ ресурсы обрабатываются автоматически. Это называется RAII .
Здесь строку можно рассматривать как «тип значения», то есть что-то, что, например, int
или double
, может быть безопасно скопировано, изменено, возвращено, передано в качестве параметра и т. Д. без риска. Это просто работает .
Часть RAII означает, что строка имеет внутренний указатель на свое содержимое (т. Е. «Тестирование»). Когда вы копируете строку, содержимое копируется. Когда вы выходите из области видимости, строка уничтожается, автоматически очищая / освобождая содержимое. Здесь нет утечек памяти.
Существуют оптимизации в зависимости от реализаций. Например, у вас может быть COW , что означает, что копия выше будет похожа на копию указателя. В других случаях строка содержит небольшой буфер, то есть небольшие строки не нуждаются в выделении / освобождении кучи.
Ваш пробег может варьироваться, но важные моменты здесь:
C way
//METHOD 2**
char nameC1[8];
const char* name1 = "testing";
strlcpy(nameC1,name1,sizeof(nameC1));
В C нет такого автоматизированного поведения, поэтому все должно быть сделано вручную, и одна измененная строка кода может сломать другую без подсказки компилятора.
В текущем случае выше, поскольку nameC1
является массивом в стеке, вы не можете его вернуть. Это довольно большой недостаток, но, с другой стороны, это означает отсутствие выделения в куче.
Другой недостаток способа C состоит в том, что вы должны использовать strlcpy
, потому что вы не хотите переполнения буфера (например, если name1 было "testingtestingtestingtesting"
вместо "testing"
), поэтому вы должны предоставить размер получаемой строки. Здесь, с массивом, это почти легко, так как sizeof
сделает свое дело (но изменит тип с char
на wchar_t
, и часть sizeof
потребуется изменить ...)
Но если тип строки nameC1
был изменен на char *
(потому что, например, вы хотите вернуть его из функции), то вам пришлось бы потенциально (пере) распределить его память для «тестирования» вписаться внутрь, это означает, что вам нужно знать длину name1
(которая может быть дорогостоящей и / или громоздкой), а затем не забывать освобождать ее, когда она больше не нужна.
Итак:
- код хрупкий, так как зависит от используемых типов. Измени одну вещь, и код не работает
- код ограничен, так как вы не можете вернуть массив, объявленный в стеке
- код, возможно, поврежден, поскольку ваш приемный буфер не может содержать более 7 + 1 символов
Заключение
Код C, приведенный выше, довольно хрупкий.
Измени одну вещь, а остальные перестанут работать должным образом. Например, изменение массива на указатель приведет к разрыву strlcpy
, поскольку он опирается на sizeof
(который, в случае указателя, вернет неправильное значение).
И даже в этом случае конечный пользователь может считать код неработающим, поскольку вы не поместите в массив C больше 7 символов плюс \0
, то есть строка, возможно, будет усечена.
Таких проблем не существует в версии кода на C ++: строки кода на C ++, естественно, будут обрабатывать все и все случаи.
Итак, вывод состоит в том, что вы должны std::string
как можно больше в своем коде, потому что это автоматизирует вещи с нулевой или предельной стоимостью.
И в тех редких случаях, когда вам нужна более быстрая обработка (обычно вы хотите удалить части выделения / освобождения кучи), вы изменяете код по мере необходимости (обычно, выделяя буфер фиксированного размера, принимая его ограничения в обмен его сильные стороны).