1

ベクター内に格納されたオブジェクトにアクセスしようとすると、セグメンテーション違反が発生します。プロセスで構成される調査があります。各プロセスは質問で構成されています。したがって、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;
}
...
};

新しいプロセス オブジェクトが作成されると、それをプロセスのベクトルに格納し、プロセス オブジェクトごとに、質問のベクトルに質問オブジェクトをプッシュします。調査オブジェクトについては、プロセス ベクトルから各プロセスを取得し、各プロセス オブジェクトについては、各質問オブジェクトを取得して印刷します。

次のコードを使用して、プロセス オブジェクトにアクセスし、正常に印刷できます。

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 に追加しています。vectorsurvey_obj

何も追加されていないため、(空の) ベクトルの末尾を超えてアクセスしているため、クラッシュが発生しています。

これを修正する 1 つの方法は、クラス メンバvectorではなく参照で返すことです。( by valueは variable のコピーと見なすことができるためです。)

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ます - ローカルの一時コピーは含まれません! 後でその質問を照会すると、予想していた場所に質問が表示されます。

最後に 2 つの注意事項: 1) 参照によって process_questions も返す必要があるかどうかを決定する必要があります。2)vector含まれている要素の数を示す機能を使用していた場合は、それが機能すると仮定するのではなく、back()この問題をより早く発見していたでしょう。:)

于 2012-05-04T18:19:29.557 に答える