Если я правильно понимаю, то в C и C++ строковые литералы хранятся в статической памяти. Поэтому указатель на строковый литерал остается валидным, фактически, до самого конца работы программы. Т.е. если мы пишем что-то вроде:
class long_living_object { const char * value_; public: long_living_object(const char * v) : value_{v} {} ... }; long_living_object make_object_ok() { return { "Hello, World!" }; } |
то у нас, в принципе, все нормально. В возвращаемом функцией make_object_ok объекте будет находиться валидный указатель.
К сожалению, в C++ нет никакого способа отличить указатель на строковый литерал от указателя на какой-то временный массив символов. Т.е., ничто в языке не запрещает нам сделать так:
long_living_object make_object_bug() { char greeting[] = "Hello, World!"; return { greeting }; } |
Чтобы использовать объекты long_living_object было безопасно, нужно скопировать содержимое передаваемой строки вовнутрь. Что требует дополнительных ресурсов, особенно когда длина строки нам заранее неизвестна и мы вынуждены использовать динамическую память.
Все это особенно обидно в ситуациях, когда мы точно знаем, что long_living_object должен содержать указатели только на строковые литералы. Например, когда long_living_object -- это что-то вроде: