Я пытался разбить строку и вставить маркеры в вектор указателей, чтобы структурировать следующим образом:
#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;
}
Проблема в том, что я получаю segfault и я точно не знаю. Раскол работает правильно. Но я не знаю, что не так.
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;
}
Ваш входной пакет размещен в стеке (локальная переменная). Когда вы выходите из функции split_queries (), экземпляр A уничтожается (деструктор называется) (более того, вы используете только один экземпляр A, объявленный в цикле). => вы должны выделить свой экземпляр A в куче (A * inputPacket = new A (item)) и не забудьте освободить его в главном или использовать вектор A (или share_ptr) вместо вектора A * ( который копирует каждый экземпляр в вектор)
A inputPacket = {item};
Создает экземпляр A в локальной области действия while, поэтому он будет удален, когда область действия будет завершена. (т. е. один раз, когда заканчивается каждый цикл). Поэтому, когда вы используете указатели позже, они уже удалены.
Вам нужно самому управлять временем жизни переменной, вручную зарезервировав для них память:
A *inputPacket = new A({item});
и избегать использования указателя на локальный объект. Тем не менее, в этом случае вам тоже придется самому управлять временем жизни. Это означает, что вам нужно будет удалить указатели. Хорошая идея автоматизировать это с помощью unique_ptr Определите свой тип возврата как:
std::vector<std::unique_ptr<A> >
, затем создайте уникальные указатели и вставьте их в вектор:
split_queries.push_back(std::make_unique<A>({item}));
Таким образом вы будете более безопасно работать с указателями.