У меня есть объект, который я пытаюсь продублировать любое количество раз с небольшими изменениями в этом объекте. Я хочу хранить указатели на эти дублированные объекты в std::vector
. Я использую for
l oop, чтобы попытаться достичь результата. Однако я заметил, что std::vector<T *>
указывает на тот же адрес после выхода из l oop. Я попробовал эту попытку дублировать объекты с std::string
, и я вижу те же эффекты. Вот мой фрагмент кода.
int main() {
auto name = new std::string("fido");
const int size = 3;
std::vector<std::string *> names;
names.reserve(size);
for (int i = 0; i < size; i++) {
std::string n = *name + " " + std::to_string(i);
names.push_back(&n);
}
// nothing from this loop prints out
for (auto n : names) {
std::cout << *n << std::endl;
}
return 0;
}
Когда я помещаю код в отладчик, я вижу, что names
хранит все указатели на один и тот же адрес памяти: 0x7ffffffeead0
. Любые идеи о том, что я делаю здесь неправильно?
Я изменил код для хранения вектора строк, а затем для l oop через каждую строку, создавая указатель на адрес каждой строки следующим образом. Этот подход также не работает. Вектор указателей все еще указывает на один и тот же адрес; хотя в этот раз все они указывают на адрес последней строки.
int main() {
auto name = new std::string("fido");
const int size = 3;
std::vector<std::string *> pointers;
std::vector<std::string> names;
names.reserve(size);
pointers.reserve(size);
for (int i = 0; i < size; i++) {
std::string n = *name + " " + std::to_string(i);
names.push_back(n);
}
for (int i = 0; i < size; i++) {
auto n = names.at(i);
auto p = &n;
pointers.push_back(p);
}
for (auto n : names) {
std::cout << n << std::endl;
}
for (auto n : pointers) {
std::cout << *n << std::endl;
}
return 0;
}
Тем не менее, в третьей попытке я модифицирую код следующим образом. Обратите внимание, что я использую оператор &
для доступа к элементу по индексу. Здесь я получаю std::vector<std::string *>
, который указывает на разные адреса (правильно соответствует вектору строк).
int main() {
auto name = new std::string("fido");
const int size = 3;
std::vector<std::string *> pointers;
std::vector<std::string> names;
names.reserve(size);
pointers.reserve(size);
for (int i = 0; i < size; i++) {
std::string n = *name + " " + std::to_string(i);
names.push_back(n);
}
for (int i = 0; i < size; i++) {
auto p = &names.at(i); // using address operator like this "works"
pointers.push_back(p);
}
for (auto n : names) {
std::cout << n << std::endl;
}
for (auto n : pointers) {
std::cout << *n << std::endl;
}
return 0;
}
Наконец, я наконец-то получил этот более лаконичный пример для работы. Здесь я создаю новый указатель на каждый l oop.
int main() {
auto name = new std::string("fido");
const int size = 3;
std::vector<std::string *> names;
names.reserve(size);
for (int i = 0; i < size; i++) {
auto x = new std::string(*name + " " + std::to_string(i));
names.push_back(x);
}
for (auto n : names) {
std::cout << *n << std::endl;
}
return 0;
}
Есть ли что-то на for-loops
и указатели, которые мне здесь не хватает? Буду признателен за любые указатели (без каламбура) на определение правил для C ++.