在我的代码中,我有多个结构,包括一些具有映射,其中第二个是指向结构的指针,如下所示:
struct course
{
college * coll;
int number;
int numprereqs;
map<int, course*> prereqs;
int numcoreqs;
map<int, course*> coreqs;
};
它编译得很好,但当它到达下面的代码或类似的代码,它正在访问地图中的特定实体时,程序崩溃。
(*currentCol).courses[newC.number] = &newC;
这是我的整个代码
头:
#ifndef courseSchedulerH
#define courseSchedulerH
#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
using namespace std;
char* inputFileName = "minimalInput.txt";
char* storageFileName = "data";
bool blahPrint = true;//if true will print out all the blahs to the terminal
bool debugnumerals = true;//Prints out line locations in the numeral area
struct college;
struct course
{
college * coll;
int number;
int numprereqs;
map<int, course*> prereqs;
int numcoreqs;
map<int, course*> coreqs;
};
struct section
{
int number;
map<int, course*> courses;
int coursesNeeded;
};
struct degree
{
college * col;
int number;
string name;
map<int, section*> sections;
};
struct college
{
int highestCourse;
string name;
map<int, course*> courses;
int degNumber;
stringstream degreesList;
map<string, degree*> degrees;
};
struct university
{
string name;//Will be needed later
int number;
stringstream collegesList;
map<string, college*> colleges;
};
struct user
{
string name;
int number;
map<int, course*> coursesTaken;
};
void baseFormat();
ifstream input;
string blah;//used for clearing fluff
bool error = false;
#endif
程序:
#include "courseScheduler.h"
int main()
{
cout << "Running!" << endl;
input.open(inputFileName);
int version;
input >> blah >> version;
input.get();
if(blah[0] != 'I')
{
cout << "No input number, stopping" << endl;
cin.get();
}
else
{
switch(version)
{
case 0:
cout << "Processing as base degree input" << endl;
baseFormat();
break;
default:
cout << "Unrecognized input number, stopping" << endl;
break;
}
cout << "Done" << endl;
cin.get();
}
}
void baseFormat()
{
bool deg = false;
bool sec = false;
bool col = false;
int sectionCount = 0;
int sectionNeed = 0;
university NMSU;
NMSU.number = 0;
degree* currentDeg;
college* currentCol;
section* currentSec;
university* currentUniv = &NMSU;
bool end = false;
while(!input.eof() && !error)
{
char c = input.peek();
cout << "Made it through, enter to continue" << endl;
cin.get();
switch(c)
{
case 'D'://Degree
{
if(end)
{
if(deg)
{
deg = false;
col = false;
end = false;
input >> blah;
if(blahPrint)cout << "blah is: " << blah << endl;
cout << "Ending degree: " << (*currentDeg).name << endl;
}
else
{
cout << "Ending a degree before initializing, stopping" << endl;
error = true;
}
}
else
{
if(col)
{
degree newDeg;
deg = true;
input >> blah >> newDeg.name;
if(blahPrint)cout << "blah is: " << blah << endl;
cout << "Starting degree: " << newDeg.name << endl;
(*currentCol).degreesList << newDeg.name << endl;
(*currentCol).degNumber++;
(*currentCol).degrees[newDeg.name] = &newDeg;
newDeg.col = currentCol;
newDeg.number = 0;
currentDeg = &newDeg;
input.get();
}
else
{
cout << "Degree with no college, stopping" << endl;
error = true;
}
}
}
break;
case 'C'://College
{
col = true;
college newCol;
input >> blah >> newCol.name;
if(blahPrint)cout << "blah is: " << blah << endl;
if(!(*currentUniv).colleges[newCol.name])
{
cout << "Starting college " << newCol.name << endl;
newCol.highestCourse = 0;
newCol.degNumber = 0;
(*currentUniv).collegesList << newCol.name << endl;
(*currentUniv).number++;
(*currentUniv).colleges[newCol.name] = &newCol;
currentCol = &newCol;
}
else
{
cout << "College of " << newCol.name << " already defined" << endl;
currentCol = (*currentUniv).colleges[newCol.name];
}
input.get();
}
break;
case 'S'://Section
{
if(end)
{
if(sec)
{
sec = false;
end = false;
input >> blah;
if(blahPrint)cout << "blah is: " << blah << endl;
cout << "ending section" << endl;
input.get();
}
else
{
cout << "Ending section before initializing, stopping" << endl;
error = true;
}
}
else
{
if(sec)
{
cout << "Section already specified, stopping" << endl;
error = true;
}
else
{
section newSec;
sec = true;
input >> blah;
if(blahPrint)cout << "blah is: " << blah << endl;
input >> newSec.coursesNeeded;
newSec.number = 0;
cout << "section with " << newSec.coursesNeeded << " needed courses" << endl;
(*currentDeg).sections[(*currentDeg).number++] = &newSec;
input.get();
}
}
}
break;
case 'E'://End
end = true;
input >> blah;
if(blahPrint)cout << "blah is: " << blah << endl;
cout << "end" << endl;
input.get();
break;
case 'O'://Other
input >> blah;
if(blahPrint)cout << "blah is: " << blah << endl;
cout << "other" << endl;
input.get();
break;
case '0'://Course Number
case '1'://Course Number
case '2'://Course Number
case '3'://Course Number
case '4'://Course Number
case '5'://Course Number
case '6'://Course Number
case '7'://Course Number
case '8'://Course Number
case '9'://Course Number
{
course newC;
input >> newC.number;
if(blahPrint)cout << "number is: " << newC.number << endl;
cout << "Numeral" << endl;
if((*currentCol).highestCourse < newC.number || !(*currentCol).courses[newC.number])
{
cout << "In that if.... should see this a lot..." << endl;
if(debugnumerals)cout << "0" << endl;
(*currentCol).courses[newC.number] = &newC;
if(debugnumerals)cout << "A" << endl;
newC.coll = &*currentCol;
if(debugnumerals)cout << "B" << endl;
if(newC.number>(*currentCol).highestCourse)
{
if(debugnumerals)cout << "C" << endl;
(*currentCol).highestCourse = newC.number;
}
}
else
{
cout << "Overlapping course of " << (*currentCol).name << " " << newC.number << endl;
cin.get();
newC = *((*currentCol).courses[newC.number]);
}
if(debugnumerals)cout << "D" << endl;
input.get();
if(debugnumerals)cout << "E" << endl;
if(sec)
{
if(debugnumerals)cout << "F" << endl;
(*currentSec).courses[(*currentSec).number++] = &newC;
}
else
{
if(debugnumerals)cout << "G" << endl;
section newS;
if(debugnumerals)cout << "H" << endl;
newS.number = 1;
if(debugnumerals)cout << "I" << endl;
newS.coursesNeeded = 1;
if(debugnumerals)cout << "J" << endl;
newS.courses[0] = &newC;
if(debugnumerals)cout << "K" << endl;
(*currentDeg).sections[(*currentDeg).number++] = &newS;
}
if(debugnumerals)cout << "L" << endl;
}
break;
default:
{
cout << "default" << endl;
input >> blah;
cout << "Unrecognized line start of " << blah << ", stopping" << endl;
}
break;
}
}
}
输入文件:
INPUT: 0
COL: C_S
DEG: COMPUTER_SCIENCE
172
271
272
273
278
370
371
372
448
471
473
474
SEC: 2
COL: C_S
470
472
475
476
478
480
481
482
483
484
485
486
491
492
END SEC
SEC: 1
COL: C_S
470
472
475
476
478
480
482
483
484
485
486
491
492
COL: MATH
291
377
430
454
480
COL: E_E
469
COL: BIOL
111
111L
211
211L
COL: CHEM
111
112
114
COL: GEOG
111
COL: GEOL
111
COL: HON
205
219
PHYS
211
211L
212
212L
215
215L
216
216L
END SEC
COL: HON
265
COL: ENGL
218
COL: MATH
280
191
192
SEC: 1
COL: MATH
331
332
377
392
430
431
454
455
END SEC
SEC: 1
COL: A_ST
311
COL: STAT
371
470
END SEC
SEC: 2
COL: ASTR
110
COL: BIOL
111
111L
211
211L
COL: CHEM
111
112
114
COL: GEOG
111
COL: GEOL
111
COL: HON
205
219
COL: PHYS
211
211L
212
212L
215
215L
216
216L
END SEC
END DEG
COL: ENGL
DEG: ENGINEERINGc_PHYSICS
111
OTHER: WRITTENCOMM
OTHER: ORALCOMM
COL: MATH
191
SEC: 1
COL: PHYS
213
213L
215
215L
END SEC
SEC: 1
COL: PHYS
214
214L
216
216L
END SEC
OTHER: AREAIV2-3
OTHER: AREAV2-3
OTHER: VWW1-2
COL: MATH
192
291
392
COL: CHEM
111
SEC: 1
COL: PHYS
451
COL: M_E
333
END SEC
OTHER: PHYS-ME2
COL: PHYS
217
217L
315
315L
395
454
455
461
462
475
COL: C_E
301
COL: M_E
102
159
236
237
240
261
326
328
338
341
426
427
449
END DEG
答案 0 :(得分:1)
在这个'C'的情况下,你在花括号内定义newCol
。该变量在堆栈内存中创建。一旦传递右括号,保持newCol
值的堆栈内存就会变为无效。
case 'C'://College
{
col = true;
college newCol;
input >> blah >> newCol.name;
if(blahPrint)cout << "blah is: " << blah << endl;
if(!(*currentUniv).colleges[newCol.name])
{
cout << "Starting college " << newCol.name << endl;
newCol.highestCourse = 0;
newCol.degNumber = 0;
(*currentUniv).collegesList << newCol.name << endl;
(*currentUniv).number++;
(*currentUniv).colleges[newCol.name] = &newCol;
currentCol = &newCol;
}
else
{
cout << "College of " << newCol.name << " already defined" << endl;
currentCol = (*currentUniv).colleges[newCol.name];
}
input.get();
}
在关闭大括号之前指定currentCol = &newCol
。在内存无效的大括号之后,可能会被覆盖。简而言之,它是垃圾。稍后您尝试使用(*currentCol).courses[...]
访问此垃圾值,这是错误的。
您需要从堆中分配,例如:
college *newCol = new college();
currentCol = newCol;
然后,在结束括号后,保存数据的内存不会变成垃圾。稍后,当您尝试访问它时,它仍将存在。