C++ 当我返回指向结构的指针向量时得到segfault
我试图拆分一个字符串,并在指向结构的指针向量中插入标记,如下所示:C++ 当我返回指向结构的指针向量时得到segfault,c++,vector,C++,Vector,我试图拆分一个字符串,并在指向结构的指针向量中插入标记,如下所示: #include <iostream> #include <vector> #include <regex> #include <sstream> using namespace std; struct A { std::string pMessage; }; std::vector<A*> splitQuery(A a) { std::vector&
#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;
}
更新和更正 实际上,我使用Uniquer\u ptr更新了代码,现在它是动态创建的,所以它在堆上,对吗?因此它不会在推回后被摧毁
#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;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
结构A{
std::字符串pMessage;
};
std::向量拆分查询(A){
std::向量分割查询;
std::stringstream ss(a.pMessage);
std::字符串项;
while(std::getline(ss,item,,')){
std::cout您的问题归结为存储一个指向具有自动存储持续时间的变量的指针,尽管指向该变量的指针被保留,但该变量将被销毁。然后
A inputPacket = {item};
声明这样一个类型,并且在push_back
语句之后超出范围
因此,代码的行为是未定义的
一个可能的修复方法是使用std::vector
作为类型,但要牺牲一些值副本。这会起作用,因为A
很容易被复制。如果这不可接受,那么使用智能指针类型的向量,例如std::unique\ptr
,并围绕的每个实例的构造进行重构de>A
您的问题归根结底是存储指向具有自动存储持续时间的变量的指针,尽管指向该变量的指针被保留,但该变量仍被销毁。然后
A inputPacket = {item};
声明这样一个类型,并且在push_back
语句之后超出范围
因此,代码的行为是未定义的
一个可能的修复方法是使用
std::vector
作为类型,但要牺牲一些值副本。这会起作用,因为A
很容易被复制。如果这不可接受,那么使用智能指针类型的向量,例如std::unique\ptr
,并围绕或者使用a(或share_ptr)的向量而不是a*(将复制向量中的每个实例)您的在堆栈上分配了一个inputPacket(局部变量)。退出函数split_querys()时,a实例将被销毁(调用析构函数)(此外,您只使用循环中声明的一个实例)。 =>必须在堆上分配一个实例(A*inputPacket=new A(item);并且不要忘记在主堆中取消分配它 或者使用a(或share_ptr)的向量代替a*(将复制向量中的每个实例)的向量 在
while
的本地作用域中创建A
的实例,因此它将在while的作用域结束时被删除(即:每个循环结束时删除一次)。因此,当您稍后使用指针时,它们已被删除
您必须通过手动为变量保留内存,自行管理变量的生存期:
A *inputPacket = new A({item});
避免使用指向本地对象的指针。但是,在这种情况下,您也必须自己管理生命周期的结束。这意味着您必须在某个地方删除指针。自动化此操作的一个好主意是使用unique\u ptr
将您的返回类型定义为:
std::vector<std::unique_ptr<A> >
std::vector
然后创建唯一指针并将其推入向量:
split_queries.push_back(std::make_unique<A>({item}));
split_查询。push_back(std::make_unique({item}));
这样,使用指针会更安全
在while
的本地作用域中创建A
的实例,因此它将在while的作用域结束时被删除(即:每个循环结束时删除一次)。因此,当您稍后使用指针时,它们已被删除
您必须通过手动为变量保留内存,自行管理变量的生存期:
A *inputPacket = new A({item});
避免使用指向本地对象的指针。但是,在这种情况下,您也必须自己管理生命周期的结束。这意味着您必须在某个地方删除指针。自动化此操作的一个好主意是使用unique\u ptr
将您的返回类型定义为:
std::vector<std::unique_ptr<A> >
std::vector
然后创建唯一指针并将其推入向量:
split_queries.push_back(std::make_unique<A>({item}));
split_查询。push_back(std::make_unique({item}));
这样,使用指针会更安全。数组中存储的指针指向临时变量。当函数splitQuery退出时,它们不再存在,但可以稍后取消引用。如果需要在超出范围后停止删除对象,则需要处理该对象的生存期因此,只需通过new运算符生成指针,而不是
inputPacket={item}我很理解你的帮助。我明白了。我学到了一些新的东西。我对C++很陌生。谢谢。请不要把这个问题加上。你应该把它作为答案。现在你的编辑使问题变得不清楚。我的意思是你的问题现在读为“我有这个不工作的代码,我固定到这个工作代码,请检查它是否正常”,但这不是问题的答案是解决(无论如何审查请求应该去)。我不会重新滚动您的编辑,但建议您这样做您的行std::unique\u ptr(新的({item}))
可以回答make\u unique({item})
您存储在数组中的指针指向临时变量。当函数splitQuery退出时,它们不再存在,但您可以稍后取消对它们的引用。如果您需要