Я опытный кодер, но все еще относительно новый для STL, и только пришли на эту проблему:Жизненный цикл объектов, передаваемых со ссылкой на STL контейнеры
Насколько мне известно, STL контейнеры не предназначены для копирования объектов, которые они содержат, или иным образом влияют на их жизненные циклы, но экспериментально я вижу разные результаты.
В частности, классы строк, которые предназначены для обнуления первого символа их базового хранилища при уничтожении, по-прежнему доступны, если они хранятся в контейнере до того, как они выйдут из области видимости. Например, рассмотрим следующий пример:
с использованием пространства имен std;
queue<string> strQueue;
const char *genStr(int i)
{
ostringstream os;
os << "The number i is " << i;
strQueue.push(os.str());
return strQueue.back().data();
}
void useStr()
{
while(!strQueue.empty())
{
cout << strQueue.front() << endl;
strQueue.pop();
}
}
int main(int argc, char **argv)
{
for(int i = 0; i < 40; i++)
{
printf("Retval is: %s\n", genStr(i));
}
useStr();
return 0;
}
Как струны выходит из области видимости, когда genStr() выходит, я бы ожидать, что Printf на только выход «RetVal является:», или, по крайней мере, для вызова useStr(), чтобы дать неопределенные результаты , так как память прерывалась повторными выделениями из дополнительных вызовов, но оба они возвращают соответствующие сохраненные строки.
Я хотел бы знать, почему это происходит, но вместо этого я был бы рад просто узнать, могу ли я полагаться на этот эффект, происходящий с любым старым объектом.
Благодаря
Я бы хотел добавить, не возвращать const char *. Используйте std :: string и std :: cout. Для этого они нужны. Мне кажется, что вы находитесь в середине конвертации с C на C++. Строковые классы не должны делать ничего такого, как обнуление их первого символа. Это будет C-ism. В C++ безопасность намного опережает это. – Puppy
Спасибо за совет. Обычно я использую std :: string и std :: cout (как вы можете видеть в useStr), что printf и возвращающий const char * были всего лишь запаникованной попыткой доказать себе, что базовые данные были все еще хорошо, и я мог бы положиться на это. –