Using: MSVS2012
Code
elemalg.h
#include <vector>
#include <string>
#include <fstream>
class ElemAlg
{
private:
std::string difficultlyLevel, question, answerToRead;
std::vector<std::string> questions, answers;
std::vector<std::string> GetQuiz(int);
};
elemalg.cpp
#include "elemalg.h"
std::vector<std::string> ElemAlg::GetQuiz(int difficulty)
{
if (difficulty == 1) { difficultyLevel = "algE"; }
if (difficulty == 2) { difficultyLevel = "algM"; }
if (difficulty == 3) { difficultyLevel = "algH"; }
if (difficulty == 4) { difficultyLevel = "algVH"; }
std::ifstream fin(difficultyLevel + ".txt");
while (std::getline(fin, question)) { questions.push_back(question); }
fin.close();
std::ifstream fin2(difficultyLevel + "Answers.txt");
while (std::getline(fin2, answerToRead)) { answers.push_back(answerToRead); }
fin2.close();
return questions;
}
MathTutor.cpp
#includes etc
ElemAlg *ea;
ea->GetQuiz(1);
GetQuiz
is definitely passed an integer between 1 and 4, this is verified before the method is called
difficultyLevel
is a string defined in the header file.
The compiler throws an Unhandled exception and Access violation writing location ... as soon as it hits the first if
function.
If I remove the if
functions and define difficultyLevel
as algE just for testing the same problem.
If I remove difficultyLevel
entirely and just open the file as "algE.txt"
and "algEAnswers"
then I get the same problem but at a different memory location once the code hits the while loop.
Your problem is here:
ElemAlg *ea;
ea->GetQuiz(1);
You're not creating an instance of ElemAlg
, so you're calling a member function on an uninitialized pointer.
Because the member function you are calling isn't virtual the compiler won't have to do any runtime lookup, which is why the call goes to GetQuiz
. However, the this
pointer will be garbage (as ea
is uninitialized), so the moment you access a member variable (such as difficultyLevel
) you'll have undefined behaviour. In your case the undefined behaviour leads to an access violation.
Either initialize ea
:
ElemAlg *ea=new ElemAlg;
ea->GetQuiz(1)
or, if you don't need to allocate it on the heap just do:
ElemAlg ea;
ea.GetQuiz(1)