>我试图拆分一个字符串并将标记插入到指向结构的指针向量中,如下所示:
#include <iostream>
#include <vector>
#include <regex>
#include <sstream>
using namespace std;
struct A {
std::string pMessage;
};
std::vector<A*> splitQuery(A a) {
std::vector<A*> split_queries;
std::stringstream ss(a.pMessage);
std::string item;
while (std::getline(ss, item, ',')) {
A inputPacket = {item};
std::cout << item << std::endl;
split_queries.push_back(&inputPacket);
}
return split_queries;
}
int main()
{
A a = {"Hello,there"};
std::vector<A *> split_queries = splitQuery(a);
std::cout << split_queries.size() << std::endl;
for (auto &s : split_queries) {
std::cout << "elements " << s->pMessage << std::endl;
}
return 0;
}
问题是我遇到了一个段错误,我不知道为什么。拆分工作正常。但我不知道出了什么问题。
Hello
there
2
Segmentation fault (core dumped)
<小时 />更新和更正
我实际上通过使用Uniquer_ptr更新了代码,现在它是动态创建的,所以它在堆上,对吧? 因此push_back后它不会被销毁。
#include <iostream>
#include <vector>
#include <regex>
#include <sstream>
#include <memory>
using namespace std;
struct A {
std::string pMessage;
};
std::vector<std::unique_ptr<A>> splitQuery(A a) {
std::vector<std::unique_ptr<A>> split_queries;
std::stringstream ss(a.pMessage);
std::string item;
while (std::getline(ss, item, ',')) {
std::cout << item << std::endl;
split_queries.push_back(std::unique_ptr<A>(new A({item})));
}
return split_queries;
}
int main()
{
A a = {"Hello,there"};
std::vector<std::unique_ptr<A>> split_queries = splitQuery(a);
std::cout << split_queries.size() << std::endl;
for (auto &s : split_queries) {
std::cout << "elements " << s->pMessage << std::endl;
}
return 0;
}
您的问题归结为存储指向具有自动存储持续时间的变量的指针,尽管保留了指向该变量的指针,但该变量仍被销毁。然后行
A inputPacket = {item};
声明这样的类型,这超出了push_back
语句之后的范围。
因此,代码的行为是未定义的。
可能的解决方法是使用std::vector<A>
作为类型,但会牺牲一些值副本。这将起作用,因为您的A
非常适合被复制。如果这是不可接受的,请使用智能指针类型的向量,例如std::unique_ptr<A>
围绕每个A
实例的构造进行重构。
A inputPacket = {item};
在while
的本地范围内创建A
的实例,因此当 while 的作用域结束时将删除该实例。(即:每个循环结束时一次。因此,当您稍后使用指针时,它们已被删除。
您必须自己管理变量的生存期,方法是手动为变量保留内存:
A *inputPacket = new A({item});
并避免使用指向本地对象的指针。但是,在这种情况下,您还必须自己管理生命周期结束。这意味着您必须在某处删除指针。自动化此操作的一个好主意是使用unique_ptr
将返回类型定义为:
std::vector<std::unique_ptr<A> >
然后创建唯一的指针并将它们推送到向量中:
split_queries.push_back(std::make_unique<A>({item}));
这样,使用指针会更安全。
您的A inputPacket在堆栈(局部变量(上分配。退出函数split_queries((时,A 实例被销毁(析构函数调用((此外,您只使用循环中声明的一个 A 实例(。 => 您必须在堆上分配 A 实例(A* inputPacket = new A(item(;并且不要忘记在 main 中解除分配它 或使用 A(或 share_ptr(的向量而不是 A* 的向量(这将复制向量中的每个实例(