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

Posted

技术标签:

【中文标题】如何访问包含指向字符串的指针的向量的元素?【英文标题】: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 【参考方案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; 以避免此类问题。

【讨论】:

以上是关于如何访问包含指向字符串的指针的向量的元素?的主要内容,如果未能解决你的问题,请参考以下文章

取消引用指向访问元素的向量指针

访问指向多维向量的指针向量中的元素

创建字符指针向量以指向字符串向量

有没有办法访问/取消引用并查找存储在双指针向量中的元素的值? [关闭]

访问指向对象指针向量的指针的第一个元素?

字符串, 向量和数组 术语表