2012-05-04 84 views
1

我在嘗試訪問存儲在矢量內的對象時出現了段錯誤。我有一個由過程組成的調查。每個過程都由問題組成。所以Survey Object包含一個vector或Processes,每個process對象包含一個問題向量。類定義如下:訪問對象矢量內的對象時出現分段錯誤

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時發生錯誤。我仍然不知道我做錯了什麼,任何幫助將不勝感激。

+0

「Question :: getProcessID」的代碼是什麼? – tmpearce

+0

類問題中沒有ProcessID變量。一個進程有問題的對象,但一個問題對象不存儲它屬於哪個進程對象。到目前爲止,我沒有看到包含它的問題的原因,但是如果我錯過了某些東西,它可以被添加。 – Atif

+0

對不起,我的意思是getQuestionID - 所以我們可以評估它是矢量訪問還是函數調用本身導致崩潰。 – tmpearce

回答

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

既然你是按值返回載體,沒有提及,要添加ques_obj到一個臨時的地方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 also returns by reference,所以ques_obj被添加到由Survey對象持有的矢量對象 - 沒有涉及本地臨時副本!稍後,當你去查詢這個問題時,你會發現它在你期望的地方。

最後兩個注意事項:1)您應該決定是否應該通過引用返回process_questions; 2)如果你已經使用vector的能力告訴你它包含了多少元素,而不是假設back()可以工作,那麼你應該早一點發現這個問題。 :)

+0

謝謝tmpearce。我現在明白這個區別。我如何將引用返回給一個向量?我知道如何在一個函數中傳遞一個向量的引用。它是這樣的 空白期函數(矢量 &v); 但下面的聲明給我一個錯誤 類調​​查{ 私人: 矢量 survey_processes; 市民: 矢量 getSurveyProcesses() { 回報&survey_processes; \t } }; – Atif

+0

在你剛給的例子,您傳回向量的*地址*(即指向它的指針)爲*引用*回報,使用稍微不同的語法:'的std ::。矢量&getSurveyProcesses(){返回survey_processes;}' – tmpearce

+0

編輯我的回答也回答後續 – tmpearce