【问题标题】:How to acces elements of a vector which contains pointers to strings?如何访问包含指向字符串的指针的向量的元素?
【发布时间】:2020-03-17 22:50:46
【问题描述】:

我正在学习向量,但遇到了一个问题,即使用指向字符串的指针创建项目向量时遇到了挑战

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;
}

但这似乎不起作用,屏幕上没有输出,然后程序随机终止。我在这里做错了什么?

【问题讨论】:

  • 您可能不想要指向字符串的指针向量。您可能需要一个字符串向量。除非您使用一些多态对象,否则您不需要任何类型的指针向量。
  • @AdrianMole 那是我的错,我在输入问题时不小心这样做了。刚刚进行了编辑。
  • @Ron 我也是这么想的,但这就是问题所暗示的
  • @dankpenny 附带说明一下,您的display() 循环超出了vector 的范围。它需要使用&lt;而不是&lt;=,并且应该使用vector&lt;string*&gt;::size_type(通常是size_t)而不是int

标签: c++ pointers vector


【解决方案1】:

在您的add_item() 函数中,thing 是一个局部变量。您正在将其地址推入向量中,但当函数返回时,thing 不再存在,因此存储在向量中的指针无效,稍后尝试取消引用将导致未定义的行为。

如 cmets 中所述,您最可能需要的是 stringobjects 的向量,而不是 stringpointers

但是,如果您真的需要使用vector&lt;string*&gt;(虽然我不认为有必要,而且我不建议这样做),那么您应该在你的 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 是在 上创建的,并且在函数返回后仍然有效。

【讨论】:

  • 在展示拥有裸指针的示例时,我会警告内存泄漏、双释放崩溃、异常安全等。
  • @eerorika 公平点!我确实提到了delete 的必要性,但也许更多?我会考虑一下的。
  • 如果要这样存储指针,请改用std::vector&lt;std::unique_ptr&lt;std::string&gt;&gt;,这样就不用担心手动调用delete了。
  • @RemyLebeau 不错的编辑 - 谢谢!我考虑了一个使用 unique_ptr 的示例,但 OP 似乎 想要使用原始指针(至少,我是这样理解这个问题的)。
【解决方案2】:

您正在将指向字符串thing 的指针添加到指向字符串的指针向量中。但是一旦add_item 返回,thing 就会超出范围。所以你添加的指针现在是一个空指针。

为什么需要指针向量?这几乎是不对的。

【讨论】:

  • 我不会说指针向量几乎永远不会正确。这不常见,当然。但是,指向 std::string 的指针。我不记得曾经有过这种需求。
【解决方案3】:

如何访问包含指向字符串的指针的向量的元素?

像这样:

*items[i]

但是,向量中的指针必须指向一个有效的对象,否则通过指针访问对象的行为是不确定的。

在您的示例中,字符串是add_item 中的自动变量。当函数返回时,包括字符串在内的所有自动变量都会被自动销毁。此时向量中的指针已经失效。通过指针间接访问对象的行为是未定义的。

我在这里做错了什么?

您尝试通过无效指针访问,程序的行为未定义。


这是一个使用指针向量的正确示例:

{
    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&lt;std::string&gt; 以避免此类问题。

【讨论】:

    猜你喜欢
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 2010-12-27
    • 2011-03-12
    • 2017-01-04
    • 1970-01-01
    相关资源
    最近更新 更多