Как получить доступ к элементам вектора, который содержит указатели на строки? - PullRequest
1 голос
/ 18 марта 2020

Я изучаю векторы и столкнулся с проблемой, которая связана с созданием вектора элементов с использованием указателей на строки

vector<string*> items;

Я пытаюсь добавить элементы, передавая список по ссылке на функция ниже:

void add_item(vector<string*> &items) {
  string thing;

  cout << "Add this item: ";
  cin  >> thing;

  string* ptr = &thing;

  items.push_back(ptr);

  return;
}

и затем отображение всех элементов, используя:

void display(vector<string*> items) {

    for (int i = 0; i <= items.size(); i++) {
        cout << "> " << *items[i] << "\n"; 
    }

    return;
}

Но это, похоже, не работает, на экране нет вывода, а затем программа случайно заканчивается Что я тут не так делаю?

Ответы [ 3 ]

2 голосов
/ 18 марта 2020

В вашей функции add_item(), thing является локальной переменной . Вы вставляете его адрес в вектор, но когда функция возвращает, то thing больше не существует, поэтому указатель, сохраненный в вашем векторе, недействителен, и попытка разыменования его позже вызовет неопределенное поведение.

Как упоминается в комментариях, что вам, скорее всего, нужен вектор string объектов , а не string указателей .

Однако, если вы действительно нужно использовать vector<string*> (хотя я не вижу необходимости, и я бы не рекомендовал это делать), тогда вам следует создать новую строку в вашей функции add_item() (и, конечно, , затем delete это при последующем удалении его из вектора):

void add_item(vector<string*> &items) {
  string *thing = new string;
  cout << "Add this item: ";
  cin  >> *thing;
  items.push_back(thing);
  return;
}
vector<string*> items;
add_item(items);
...
for (size_t i = 0; i < items.size(); ++i) {
    delete items[i]; 
}

В этом случае thing создается в куче и останется действителен после возврата функции.

1 голос
/ 18 марта 2020

Как получить доступ к элементам вектора, который содержит указатели на строки?

Примерно так:

*items[i]

Однако указатель в векторе должен указывать на действительный объект, иначе поведение доступа к объекту через указатель не определено.

В вашем примере строка является автоматической c переменной в add_item. Когда функция возвращается, все автоматические c переменные, включая строку, автоматически уничтожаются. В этот момент указатель в векторе стал недействительным. Поведение косвенного обращения через указатель и доступа к объекту не определено.

Что я здесь не так делаю?

Вы пытаетесь получить доступ через недопустимый указатель и поведение программа не определена.


Вот правильный пример с использованием вектора указателей:

{
    std::string thing = "example";
    items.push_back(&thing);
    display(items);
    items.pop_back();  // erase the pointer that is about to be invalidated
}
// the string no longer exists here

Обратите внимание на то, как строка все еще существует, когда она отображается.

Но вы, вероятно, должны использовать std::vector<std::string> вместо этого, чтобы избежать таких проблем.

1 голос
/ 18 марта 2020

Вы добавляете указатель на строку thing на вектор указателей на строки. Но как только add_item возвращается, thing выходит из области видимости. Итак, указатель, который вы добавили, теперь является указателем на ничто.

Зачем вам нужен вектор указателей? Это почти никогда не верно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...