Со следующим:
#include <set>
std::set<const char *> global = std::set<const char *>();
void x() {
const char *c = "a";
const char *d = "b";
global.insert(c);
global.insert(d);
}
int main() {
x();
for (std::set<const char *>::const_iterator iter=global.begin(), end=global.end(); iter!=end; ++iter) {
printf("%s\n", *iter);
}
return 0;
}
В итоге, как и ожидалось, я получаю a
а также b
распечатаны.
Тем не менее, есть ли гарантия, что, например, если этот набор был частью bozo
объект, который как набор они продлились бы до конца bozo
жизнь? Или мне придется strdup
струны, чтобы быть уверенным?
У вас все хорошо, потому что строковые литералы имеют статическую длительность хранения. То есть строка будет храниться в памяти на протяжении всей программы. Тем не менее, было бы не хорошо, если бы вы объявили c
а также d
как массивы вроде так:
const char c[] = "a";
const char d[] = "b";
Это происходит потому, что когда массив инициализируется строковым литералом, символы из литерала копируются в массив. Этот массив имеет автоматическую продолжительность хранения, поэтому содержимое будет уничтожено в конце функции x
, Если вы все еще сделали global.insert(c)
, вы бы нажали указатель на первый элемент c
массив, но этот массив не будет существовать намного дольше.
Вот несколько стандартных цитат. Во-первых, §2.14.5 / 8:
Обычные строковые литералы и строковые литералы UTF-8 также упоминаются как узкие строковые литералы. Узкий строковый литерал имеет тип «массив N
const char
«, где N это размер строки, как определено ниже, и имеет статическую продолжительность хранения (3.7).
А теперь определение статической продолжительности хранения (§3.7.1 / 1):
Все переменные, которые не имеют динамической длительности хранения, не имеют длительности хранения потока и не являются локальными, имеют статическая продолжительность хранения. Хранение для этих объектов должно продолжаться в течение всей программы (3.6.2, 3.6.3).
Других решений пока нет …