我试图拆分一个字符串并将标记插入结构的指针向量中,如下所示:
#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;
}
答案 0 :(得分:2)
您的问题归结为您使用 automatic 存储持续时间存储了指向变量的指针,并且尽管保留了指向该变量的指针,该变量也被销毁了。然后行
A inputPacket = {item};
声明了这种类型,并且在push_back
语句之后超出了范围。
因此,您的代码的行为是未定义。
一种可能的解决方法是使用std::vector<A>
作为类型,但会牺牲一些值副本。由于您的A
很容易被复制,因此将起作用。如果不能接受,则使用智能指针类型的向量,例如std::unique_ptr<A>
,并围绕A
的每个实例的构造进行重构。
答案 1 :(得分:1)
A inputPacket = {item};
在A
的本地范围内创建while
的实例,因此,当while范围结束时,它将被删除。 (即:每个循环结束一次。)因此,以后使用指针时,它们已被删除。
您必须通过手动为变量保留内存来管理变量的生命周期:
A *inputPacket = new A({item});
,并避免使用指向本地对象的指针。但是,在这种情况下,您也必须自己管理生命周期的结束。这意味着您必须删除某个地方的指针。要实现此目的,一个不错的主意是使用unique_ptr
将返回类型定义为:
std::vector<std::unique_ptr<A> >
然后创建唯一的指针并将其推入向量:
split_queries.push_back(std::make_unique<A>({item}));
这样,您将更安全地使用指针。
答案 2 :(得分:0)
您的 inputPacket 已分配在堆栈上(局部变量)。退出函数 split_queries()时,A实例被销毁(调用了析构函数)(此外,您仅使用循环中声明的A实例)。 =>您必须在堆上分配您的A实例( A * inputPacket = new A(item); ),并且不要忘记在主实例中分配它 或使用A(或share_ptr)的向量而不是A *的向量(它将复制向量中的每个实例)