Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当我返回指向结构的指针向量时得到segfault_C++_Vector - Fatal编程技术网

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
,并围绕的每个实例的构造进行重构de>A

您的inputPacket在堆栈(局部变量)上分配。退出函数split_querys()时,A实例被销毁(调用析构函数)(而且您只使用循环中声明的A的一个实例)。 =>必须在堆上分配一个实例(A*inputPacket=new A(item);并且不要忘记在主堆中取消分配它
或者使用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退出时,它们不再存在,但您可以稍后取消对它们的引用。如果您需要