Строки Printf и C ++

Итак, у меня есть следующий код:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main() {
vector<string> strs;
strs.push_back("happy");
const string& a1 = strs[0];
strs.push_back("birthday");
const string& a2 = strs[1];
strs.push_back("dude");
const string& a3 = strs[2];

printf("%s\n", a1.c_str());
return 0;
}

что довольно просто, но не работает.
Printf ничего не печатает.
Это действительно печатает, если я изменяю это на:

const string& a1 = strs[0].c_str();

Может кто-нибудь, пожалуйста, объясните поведение этого.

2

Решение

Ваши звонки на push_back потенциально (и в вашем случае, очевидно, фактически) сделать недействительными все ссылки в vectorа именно если vector слишком мал для хранения нового элемента. Таким образом, вы не можете использовать какие-либо ссылки на vector созданный до push_back если вы не уверены, что vectorЕмкость достаточно большая.

Если вы убедитесь, что vector имеет достаточную емкость для всех элементов (т.е. используя std::vector::reserve) до вы создаете ссылки, ваша первая версия будет работать как положено.

Ваш второй пример работает, потому что вы создаете новый, временный string (время жизни которого увеличено до времени жизни ссылки) ссылка связывается с.

8

Другие решения

strs.push_back("happy");
const string& a1 = strs[0];

Ваша ссылка действительна до этого момента. Однако следующий push_back создает проблемы

strs.push_back("birthday");

Это увеличивает емкость вектора с 1 до 2.
Поскольку новая емкость больше старой, все ссылки (а также итераторы), созданные до этой точки на векторе, становятся недействительными.

Как примечание стороны,
C_str дает вам символ * (завершенная строка \ 0).
Если ваша вставка была в форме

strs.push_back("happ\0y");
const string& a1 = strs[0].c_str();

a1 будет иметь значение ‘happ’

1