尝试访问结构中的地图时,程序会冻结

时间:2013-04-14 04:45:12

标签: c++ pointers map structure

在我的代码中,我有多个结构,包括一些具有映射,其中第二个是指向结构的指针,如下所示:

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

1 个答案:

答案 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;

然后,在结束括号后,保存数据的内存不会变成垃圾。稍后,当您尝试访问它时,它仍将存在。