Я делаю оболочку с помощью Linux (WSL). По какой-то неизвестной причине, когда я возвращаю указатель структуры (который я сделал) в вектор, он вызывает SIGNALSEGV.
Это основные классы проблемного кода,
class TimeoutCommand : public BuiltInCommand {
public:
bool background;
std::string line;
int pid;
int duration;
TimeoutCommand(const char* cmd_line); //prepare line
virtual ~TimeoutCommand() {}
void execute() override; ////set alarm + fork + add to joblist + add to timelist
};
class TimeoutList{
public:
struct TimeoutEntry {
std::string line;
int pid;
time_t start_time;
int duration;
TimeoutEntry(int pid,time_t start_time,std::string line,int duration)
:pid(pid),start_time(start_time),line(line),duration(duration)
{};
};
std::vector<TimeoutEntry*> TimeoutVec;
TimeoutList();
~TimeoutList() {
for (TimeoutEntry *entry : TimeoutVec)
delete entry;
}
void addCommand(TimeoutCommand* cmd); ////add new timeout
void timeoutCheck(); ////timout timedoutcommands
};
Это конструктор TimeoutCommand и строка, вызывающая проблемную функцию:
TimeoutCommand::TimeoutCommand(const char *cmd_line)
:BuiltInCommand(cmd_line)
{
_parseCommandLine(cmd_line,args);
background=_isBackgroundComamnd(cmd_line);
for(int i=2;args[i]!=NULL;i++) {
line +=args[i];
}
duration=stoi(args[1]);
}
void TimeoutCommand::execute() {
alarm(duration);
**SmallShell::getInstance().timouts->addCommand(this);**
...
...
...
И, наконец, вот проблемная функция:
void TimeoutList::addCommand(TimeoutCommand *cmd) {
time_t t= time(NULL);
if (t==-1){
perror("smash error: time failed");
return;
}
TimeoutEntry* entry = new TimeoutEntry(cmd->pid,t,cmd->line,cmd->duration);
**TimeoutVec.push_back(entry);**
}
Что вызывает ошибку сегментации? Я не вижу никаких странных ошибок указателя или чего-то подобного сразу.
выполнение этой команды будет выглядеть примерно так: timeout 3 sleep 10
Что будет cmd_line
Это часть std::vector, которая вызывает segfault
push_back(const value_type& __x)
{
**if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)**
{
_GLIBCXX_ASAN_ANNOTATE_GROW(1);
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
__x);
++this->_M_impl._M_finish;
_GLIBCXX_ASAN_ANNOTATE_GREW(1);
}
else
_M_realloc_insert(end(), __x);
}
**Проблемные строки отмечены ** **
std::vector<TimeoutEntry*> TimeoutVec;
вместоstd::vector<TimeoutEntry> TimeoutVec;
? Или, если вы должны использовать указатели:std::vector<std::unique_ptr<TimeoutEntry>> TimeoutVec;
? - person PaulMcKenzie   schedule 26.04.2021new
в вашем приложении необходимо тщательно управлять памятью. Если у вас просто былstd::vector<TimeoutEntry>
, то не нужно вручную управлять памятью. Тогда строка, с которой у вас возникли проблемы, будет просто:TimeoutVec.push_back({cmd->pid,t,cmd->line,cmd->duration});
, без вызоваnew
. - person PaulMcKenzie   schedule 26.04.2021new
иx
строк вызововdelete
, так что все в порядке. Помните, что существует поток программы, и вы не знаете или не уверены, как работает код. Это не так просто, как просто подсчитать количество вызововnew
иdelete
в исходном коде. - person PaulMcKenzie   schedule 26.04.2021TimeoutList
. Мы понятия не имеем, допустим этот экземплярTimeoutList
или нет. Вот почему следует опубликовать минимально воспроизводимый пример. - person PaulMcKenzie   schedule 26.04.2021