Итак, у меня есть следующий код:
#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();
Может кто-нибудь, пожалуйста, объясните поведение этого.
Ваши звонки на push_back
потенциально (и в вашем случае, очевидно, фактически) сделать недействительными все ссылки в vector
а именно если vector
слишком мал для хранения нового элемента. Таким образом, вы не можете использовать какие-либо ссылки на vector
созданный до push_back
если вы не уверены, что vector
Емкость достаточно большая.
Если вы убедитесь, что vector
имеет достаточную емкость для всех элементов (т.е. используя std::vector::reserve
) до вы создаете ссылки, ваша первая версия будет работать как положено.
Ваш второй пример работает, потому что вы создаете новый, временный string
(время жизни которого увеличено до времени жизни ссылки) ссылка связывается с.
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’