当我返回指向结构的指针向量时出现段错误



>我试图拆分一个字符串并将标记插入到指向结构的指针向量中,如下所示:

#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* 的向量(这将复制向量中的每个实例(

最新更新