为什么访问此局部成员变量会导致异常
Why would accessing this local member variable cause an exception?
我正在尝试编写一个程序,该程序会将.csv文件的内容读取到数组中,然后将结果打印到屏幕上(较大项目的一部分),当调用函数getNumberOfRooms()
时,当它尝试返回numberOfRooms
变量(类中的私有成员)的值时,会引发异常。 以前有没有人遇到过这样的问题或帮助某人解决这种问题问题?如果是这样,你是如何解决的?
提前感谢,
此处提供完整的源代码:https://bitbucket.org/skutov/micropuzzle/
调用 getNumberOfRooms() 时引发的异常:
Unhandled exception at 0x01354aa6 in MICROPUZZLE.exe: 0xC0000005: Access violation
reading location 0xccccccd0.
这些是有问题的函数(在类中引用变量的所有时间)
ClassMap::ClassMap ()
{
numberOfRooms = 0;
// Get number of rooms in map.csv
/* Find number of entries in map.csv file */
numberOfRooms = number_of_lines;
// allocate memory for rooms array
/* loading data from file into array */
}
}
// self explanitory
int ClassMap::getNumberOfRooms()
{
// Exception occurs on this line when accessing the variable
return numberOfRooms;
}
int ClassMap::printRoomDescriptions ()
{
for(int j = this->getNumberOfRooms(); j > 0; j--)
{
cout << roomArray[j].getDescription();
}
return 0;
}
这是类标头:
class ClassMap
{
private:
int currentLocation;
int numberOfRooms;
// pointer to array initialised in constructor
ClassRoom *roomArray;
public:
// Constructors and Destructors
ClassMap();
~ClassMap();
// Print description, events and directions for current room
std::string getCurrentRoom();
// Change currentLocation to neighbour of current room if possible
int moveRoom(char direction);
// self explanitory
int getNumberOfRooms();
// dump room descriptions to command line (debugging)
int printRoomDescriptions();
};
下面是 ClassMap 的构造函数,它也初始化 roomArray:
ClassMap::ClassMap ()
{
numberOfRooms = 0;
// Get number of rooms in map.csv
unsigned int number_of_lines = 0;
FILE *infile = fopen("map.csv", "r");
int ch;
while (EOF != (ch=getc(infile)))
if ('n' == ch)
++number_of_lines;
fclose(infile);
numberOfRooms = number_of_lines;
// allocate memory for rooms array
roomArray = new ClassRoom[numberOfRooms+1];
// set starting room
int currentLocation = 1;
// load that shit up
{
// Holders for values read from file
int newRoomID = 0;
char newRoomDescription[79] = "";
int newRoomNorthNeighbour = 0;
int newRoomEastNeighbour = 0;
int newRoomSouthNeighbour = 0;
int newRoomWestNeighbour = 0;
// used for iterations
int i = 0;
// File stream for map.csv
std::ifstream mapFile;
// Crack that shit open
mapFile.open ("map.csv");
// Line buffer for parsing
std::string line;
// For each line in the map.csv file read in the values into variables declared above then run initialise function for each room to store values into array
while (std::getline(mapFile, line))
{
// re-init parameters
newRoomID = 0;
newRoomNorthNeighbour = 0;
newRoomEastNeighbour = 0;
newRoomSouthNeighbour = 0;
newRoomWestNeighbour = 0;
for(i = 0;i<79;i++)
{
newRoomDescription[i] = ' ';
}
int parameter = 0;
int paraStart = 0;
int paraEnd = 0;
std::string buffer;
std::istringstream iss(line);
for(parameter = 0; parameter <= 5; parameter++)
{
// Empty buffer from last iteration
buffer.clear();
// Find end of current parameter
paraEnd = line.find(',',paraStart+1);
switch (parameter)
{
case 0:
buffer = line.substr((paraStart),(paraEnd-paraStart));
newRoomID = atoi(buffer.c_str());
break;
case 1:
buffer = line.substr((paraStart+2),(line.find(""",paraStart+2)-(paraStart+2)));
for(i = 0;i<(buffer.length());i++)
{
newRoomDescription[i] = buffer.c_str()[i];
}
//newRoomDescription
break;
case 2:
buffer = line.substr((paraStart+1),(paraEnd-paraStart));
newRoomNorthNeighbour = atoi(buffer.c_str());
break;
case 3:
buffer = line.substr((paraStart+1),(paraEnd-paraStart));
newRoomEastNeighbour = atoi(buffer.c_str());
break;
case 4:
buffer = line.substr((paraStart+1),(paraEnd-paraStart));
newRoomSouthNeighbour = atoi(buffer.c_str());
break;
case 5:
buffer = line.substr((paraStart+1),(paraEnd-paraStart));
newRoomWestNeighbour = atoi(buffer.c_str());
break;
} // switch
// Cycle paraEnd to paraStart
paraStart = paraEnd;
} // for parameters loop
// Init next room with data
new (&roomArray[newRoomID]) ClassRoom( newRoomNorthNeighbour,
newRoomEastNeighbour,
newRoomSouthNeighbour,
newRoomWestNeighbour,
newRoomDescription);
} // while !EOF
// Close the file because we're a good little program and we don't need that shit no more
mapFile.close();
}
}
这个问题的关键是:
Access violation reading location 0xccccccd0
0xcccccccc
是在调试模式下用于表示单位化指针的特殊值。(请参阅如何以指向0xCCCCCCCC的指针结束)它在调试模式下设置为导致这种崩溃 - 这意味着您正在使用的指针尚未设置。正确设置指针后,错误将消失。(与0xcccccccc
的细微区别是您尝试在该对象内访问的成员的偏移量。
添加:
这是你的错误:
ClassRoom* roomArray = static_cast<ClassRoom*>( ::operator new ( sizeof ClassRoom * numberOfRooms ) );
这将创建一个局部roomArray
变量,并隐藏该成员变量。你真正想要的是:
roomArray = static_cast<ClassRoom*>( ::operator new ( sizeof ClassRoom * numberOfRooms ) );
或者更好的是:
roomArray = new ClassRoom[numberOfRooms];
问题是你的 for 循环for(int j = this->getNumberOfRooms(); j > 0; j--)
.它应该看起来像这样:for(int j = this->getNumberOfRooms()-1; j >= 0; j--)
.包含 N 个条目的 arry 中最后一个可访问索引是 N-1。另一方面,第一个索引为 0。
- 赋予全局变量而不是局部变量优先级的函数 - (异常行为)
- 当使用lambda进行变量的复杂初始化时,如何处理从内部抛出的lambda外部异常
- 在类声明中初始化 const 成员变量时在调试模式下出现异常
- memcpy() 在一个类中被调用以复制到另一个类变量中后会引发异常
- 声明一个额外的变量会导致运行时出现异常
- 如果函数抛出的异常可能未捕获,如何销毁局部变量?
- GCC和Clang不警告未使用的异常变量
- 在 C++ 中的构造函数中引发异常时销毁对象的成员变量
- C++ 读取文件和写入变量时未处理的异常 - getline 错误?
- 如何释放C++异常类析构函数中的变量
- 基本类型变量的赋值计算序列,右操作数引发异常
- 条件变量wait引发异常
- 如果在静态局部变量之前出现异常,会发生什么
- 由将值分配给双精度类型的变量而导致的浮点异常
- 异常处理和成员变量
- 异常变量声明
- DLL 中的 C++ 静态局部变量初始化会导致_CrtIsValidHeapPointer异常
- 如何抛出带有变量消息的 std::异常
- 变量 C++ 的异常初始化
- 当异常变量未定义时,通过引用捕获