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

时间:2012-05-04 16:24:46

标签: c++

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

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;
}
...
};

创建新的流程对象时,我将其存储在Processes的向量中,对于每个Process Object,我将Question对象推送到Questions的向量中。对于调查对象,我想从Process Vector和每个Process Object获取每个Process,获取每个问题对象并打印它。

我可以使用以下代码访问Process Objects并成功打印它们。

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

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

以下是发生分段故障的代码的相关部分。

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时发生错误。我仍然不知道我做错了什么,任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:4)

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

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

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

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

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 also returns by reference,所以ques_obj被添加到由Survey对象持有的向量所持有的对象 - 不涉及本地的临时副本!之后,当您去查询该问题时,您会在预期的位置找到它。

最后两个注释:1)您应该决定是否也应该通过引用返回process_questions; 2)如果你曾使用vector的能力来告诉你它包含了多少元素,而不是假设back()可以工作,那么你早就会发现这个问题。 :)