C++:访问位置写入违规

9

使用:MSVS2012

代码

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",那么一旦代码进入while循环,我会得到同样的问题,但在不同的内存位置。


参数应该在函数内部使用assert进行验证,而不是在外部。如果“questions”是全局变量,我不知道为什么你要尝试返回它。 - Neil Kirk
MCVE 或者就没有发生过。 - Angew is no longer proud of SO
1
您的ElemAlg对象无效。我认为您需要将代码周围的内容发送给我们。 - ChrisWard1000
请编辑您的问题并至少显示确切类型。如果您说“string”,我想您实际上是指std::string - πάντα ῥεῖ
1
@user3001499 - 如果我删除if函数并将difficultyLevel定义为algE,只是为了测试同样的问题,那么你应该停止删除代码,而是保留原有有问题的代码,并学习为什么会出现问题并修复它。删除代码可能会隐藏错误,让你产生虚假的感觉,认为通过“魔法”解决了问题。 - PaulMcKenzie
显示剩余5条评论
1个回答

24

你的问题在这里:

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

你没有创建一个 ElemAlg 的实例,所以你在一个未初始化的指针上调用了一个成员函数。

因为你调用的成员函数不是虚函数,编译器就不会进行任何运行时查找,这就是为什么调用转到了 GetQuiz。然而,this 指针将是垃圾值(因为 ea 未初始化),所以一旦你访问成员变量(如 difficultyLevel),你将会产生未定义行为。在你的情况下,未定义的行为导致了访问冲突。

要么初始化 ea

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

或者,如果你不需要在堆上分配它,只需执行:

ElemAlg ea;
ea.GetQuiz(1)

1
非常感谢...我的程序不同,但它帮助我解决了问题... 我只是用new关键字改变了内存分配语句 使用以下语句仍然会出现相同的错误: MyQueue *newnode = (MyQueue*)malloc(sizeof(MyQueue)); 将上述语句改为: MyQueue *newnode = new MyQueue; - RAVI VAGHELA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接