访问对象向量内的对象时出现分割错误

Segmentation fault while accessing an object inside a vector of object

本文关键字:对象 分割 错误 向量 访问      更新时间:2023-10-16

我在尝试访问存储在向量中的对象时遇到分段错误。我有一个由流程组成的调查。每个过程都由问题组成。因此,调查对象包含一个或多个流程,每个流程对象包含一个问题向量。类定义如下:

class Survey {
private:
...
vector <Process> survey_processes;
....
public:
......
vector<Process> getSurveyProcesses()
{ return survey_processes;  }
void addProcessObj(Process obj)
{ survey_processes.push_back(obj);}
.....
};
class Process
 { 
private:
....
vector<Question> proc_questions;
....
public:
...
vector<Question> getProcessQuestions()
{ return proc_questions;}
void addQuestionObj(Question obj)
{ proc_questions.push_back(obj); }
.....
};
class Question {
private:
int quesnum;
int answer;
...
public:
Question (int c_ques, int c_ans)
{
quesnum = c_ques;
answer = c_ans;
}
int getQuestionID()
{
    return quesnum;
} 
int getAnswer()
{
    return answer;
}
...
};
创建新的流程对象

时,我将其存储在流程向量中,对于每个流程对象,我将问题对象推送到问题向量中。对于调查对象,我想从流程向量中获取每个流程,对于每个流程对象,获取每个问题对象并打印出来。

我可以使用以下代码访问流程对象并成功打印它们。

cout << ((survey_obj.getSurveyProcesses()).back()).getProcessID() << endl;

当我尝试从流程向量中提取问题对象时,它给了我一个分割错误。我相信我在尝试访问该对象时犯了一些语法错误。 如何访问嵌入在给定流程对象的问题向量中的问题对象,该向量位于给定调查对象的流程对象向量内?

下面是发生分段错误的代码的相关部分。

int procnum = 0;
for (unsigned i = 11; i < all_words.size()-1; ++i)
{   
vector<string> v;
string s = all_words.at(i);
stringstream ques_stream(s);
int ques_num;
ques_stream >> ques_num;
ques_stream.ignore();   
// if process object already exists, do nothing. Otherwise create a new process object and add it to the survey object  
if (procnum == ques_num)
    ;
else    
{   
Process proc_obj(ques_num);
survey_obj.addProcessObj(proc_obj);
procnum = ques_num;
}
string ques_strng;  
ques_stream >> ques_strng;
ques_stream.ignore();
Question ques_obj(ques_strng);
// objective: put the new question object in the question vector of the last process object from the process vector of the survey object
cout << ((survey_obj.getSurveyProcesses()).back()).getProcessID() << endl;
Process current_proc_obj = (survey_obj.getSurveyProcesses()).back();
cout << " Current Process : " << current_proc_obj.getProcessID() << endl;
Question current_question_obj = (current_proc_obj.getProcessQuestions()).back();

((survey_obj.getSurveyProcesses()).back()).addQuestionObj(ques_obj);    
**// this is where the segmentation fault occurs when i try to get the last object from process vector of the survey and for that object get the last element of the question vector. print the question id of this question object     
cout << " Current Question : " << ((((survey_obj.getSurveyProcesses()).back()).getProcessQuestions()).back()).getQuestionID() << endl;**
cout << " Current Process Question : " << ((current_proc_obj.getProcessQuestions()).back()).getQuestionID() << endl;
}

我尝试运行 gdb 调试器,但它只告诉我在尝试访问 questionID 时发生错误。我仍然不知道我做错了什么,任何帮助将不胜感激。

((survey_obj.getSurveyProcesses()).back()).addQuestionObj(ques_obj);
             _______________copy^, _copy^ -               ^_______added to copy

由于您是按值而不是引用返回向量,因此您将ques_obj添加到临时本地vector,而不是由survey_obj持有的向量。

发生崩溃是因为您正在访问(空(向量的末尾,因为没有添加任何内容。

解决此问题的一种方法是按引用而不是按值返回类成员vector。 (因为 by 值可以作为变量的副本

class Survey {
private:
vector <Process> survey_processes;
public:
vector<Process>& getSurveyProcesses()//<--ampersand indicates return by reference 
{ return survey_processes;  }
};

现在,当您尝试此操作时:

((survey_obj.getSurveyProcesses()).back()).addQuestionObj(ques_obj);
                          ______^ this is the vector inside the Survey class,
                                  not a copy

幸运的是,std::vector::back 也通过引用返回,因此ques_obj被添加到由 vector 持有的对象中,由Survey对象持有 - 不涉及本地临时副本! 稍后,当您去查询该问题时,您会在预期的位置找到它。

最后两点:1(您应该决定是否也应该通过引用返回process_questions;2(如果你使用vector的能力来告诉你它包含多少元素,而不是仅仅假设back()会起作用,你会更早地发现这个问题。:)