2014-10-20 2 views
5

Использование: MSVS2012C++: нарушение прав доступа месте для записи

Код

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 определенно прошло целое число от 1 до 4, это проверяется, прежде чем метод называется

difficultyLevel является строка определена в заголовочном файле.

Компилятор выбрасывает Необработанное исключение и место записи нарушения доступа ... как только он попадает в первую функцию if.

Если я удалю функции if и определите difficultyLevel как algE только для проверки той же проблемы.

Если удалить difficultyLevel целиком и просто открыть файл как "algE.txt" и "algEAnswers" тогда я получаю ту же проблему, но в другом месте памяти после того, как код попадает в то время цикла.

+0

Что такое 'difficultyLevel' именно? –

+0

Параметр должен быть проверен внутри функции с утверждением, а не снаружи. Если вопросы являются глобальной переменной, я не знаю, почему вы пытаетесь ее вернуть. –

+0

[MCVE] (http://stackoverflow.com/help/mcve), или этого не произошло. – Angew

ответ

13

Ваша проблема здесь:

ElemAlg *ea; 
ea->GetQuiz(1); 

Вы не создаете экземпляр ElemAlg, поэтому вы вызываете функцию-член неинициализированного указателя.

Поскольку функция-член, которую вы вызываете, не является виртуальной, компилятору не требуется выполнять поиск во время выполнения, поэтому вызов переходит к GetQuiz. Тем не менее, указатель будет мусором (так как ea неинициализирован), поэтому в момент доступа к переменной-члену (например, difficultyLevel) у вас будет неопределенное поведение. В вашем случае неопределенное поведение приводит к нарушению доступа.

Либо инициализировать ea:

ElemAlg *ea=new ElemAlg; 
ea->GetQuiz(1) 

или, если вам не нужно выделить его в куче просто сделать:

ElemAlg ea; 
ea.GetQuiz(1) 
+1

Большое вам спасибо ... моя программа отличается, но это помогло мне решить мою проблему ... Я просто изменил оператор выделения памяти с помощью нового ключевого слова Получение такой же ошибки с помощью оператора: MyQueue * newnode = (MyQueue *) malloc (sizeof (MyQueue)); ' \t \t Измените инструкцию выше: MyQueue * newnode = new MyQueue;' –

Смежные вопросы