如何访问包含指向字符串的指针的向量的元素?
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
的范围。它需要使用<
而不是<=
,并且应该使用vector<string*>::size_type
(通常是size_t
)而不是int
。
【参考方案1】:
在您的add_item()
函数中,thing
是一个局部变量。您正在将其地址推入向量中,但当函数返回时,thing
不再存在,因此存储在向量中的指针无效,稍后尝试取消引用将导致未定义的行为。
如 cmets 中所述,您最可能需要的是 string
objects 的向量,而不是 string
pointers。
但是,如果您真的需要使用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
是在 堆 上创建的,并且在函数返回后仍然有效。
【讨论】:
在展示拥有裸指针的示例时,我会警告内存泄漏、双释放崩溃、异常安全等。 @eerorika 公平点!我确实提到了delete
的必要性,但也许更多?我会考虑一下的。
如果要这样存储指针,请改用std::vector<std::unique_ptr<std::string>>
,这样就不用担心手动调用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<std::string>
以避免此类问题。
【讨论】:
以上是关于如何访问包含指向字符串的指针的向量的元素?的主要内容,如果未能解决你的问题,请参考以下文章