1

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

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;

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

4

1 回答 1

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

由于您是按值而不是引用返回向量,因此您正在添加ques_obj到一个临时的 local vector,而不是survey_obj.

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

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 也通过引用返回,因此ques_obj被添加到由向量持有的对象中,由Survey对象持有 - 不涉及本地临时副本!稍后,当您去查询该问题时,您会在预期的位置找到它。

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

于 2012-05-04T18:19:29.557 回答