Ошибка сегментации в определениях классов не может определить, где

0

У меня ошибка сегментации, которую я пытался найти в течение последних 4 часов. Вот код и некоторая информация, которая может быть полезной из valgrind.

  Course::Course()
{
    courseid = "None";
    courseName = "None";
    enrolled[2] = {0};

}

Course::Course(string courseNum, string coursename, string filename)
{
    courseid = courseNum;
    courseName = coursename;
    enrolled[2] = {0};
    readStudentData(filename);
    sortRow(0);
    sortRow(1);
    sortRow(2);

}


void Course::readStudentData(string filename)
{
    std::ifstream inFile; //declare file input stream object
    string first, last, zid;
    int section;

    inFile.open(filename.c_str()); //open file 
    if (!inFile)
    {
        cout << "File did not open successfully!"; //error checking
        exit(EXIT_FAILURE);
    }

    inFile >> first; //read first
    while (inFile)
    {
        inFile >> last;
        inFile >> zid;
        inFile >> section;
        section--; //match section with array subscript

        Student newStudent(last, first, zid);   //fill  contents read to new student object



        Students[section][enrolled[section]] = newStudent; //fill Students array with new student 

        enrolled[section]++; //add the student to the enrolled counter

        inFile >> first;
    }

    inFile.close();
}


void Course::sortRow(int RowtoSort)
{
    int i, j;
    Student bucket;

    for(i = 1; i < enrolled[RowtoSort];i++)
    {
        bucket = Students[RowtoSort][i]; //assign bucket with temp value for swap


            for(j = i; (j > 0) && (Students[RowtoSort][j-1].getLastName().compare(bucket.getLastName())) < 0; j--)
        {
            Students[RowtoSort][j] = Students[RowtoSort][j-1]; //assign j to element j-1 so now both j and j-1 are the same in the array
        }
        Students[RowtoSort][j] = bucket; //now j-1 value is at j and since j-- assign it to bucket to place the proper value at j-1  

    } // end outer loop

}


void Course::print()
{
    cout << courseid << " " << courseName << endl; //header

    cout << "Section 1" << endl; //print section 1
    cout << left << "Name" << setw(40) << "Z-id" << endl;

    for(int i=0;i<enrolled[0];i++)
    {
        Students[0][i].print();          
    }

    cout << "Section 2" << endl;    //print section 2
    cout << left << "Name" << setw(40) << "Z-id" << endl;
    for(int i=0;i<enrolled[0];i++)
    {
        Students[1][i].print();   
    }

    cout << "Section 3" << endl;    //print section 3
    cout << left << "Name" << setw(40) << "Z-id" << endl;
    for(int i=0;i<enrolled[0];i++)
    {
        Students[2][i].print();   
    }


}

Вот информация, которую дал valgrind, когда

==4223== Use of uninitialised value of size 8
==4223==    at 0x4EF15F1: std::string::assign(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==4223==    by 0x4023E6: Student::operator=(Student const&) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x401B9F: Course::readStudentData(std::string) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x401836: Course::Course(std::string, std::string, std::string) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x4012F9: main (assign3.cpp:27)
==4223== 
==4223== Use of uninitialised value of size 8
==4223==    at 0x4EF15F1: std::string::assign(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==4223==    by 0x402401: Student::operator=(Student const&) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x401B9F: Course::readStudentData(std::string) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x401836: Course::Course(std::string, std::string, std::string) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x4012F9: main (assign3.cpp:27)
==4223== 
==4223== Use of uninitialised value of size 8
==4223==    at 0x4EF15F1: std::string::assign(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==4223==    by 0x40241C: Student::operator=(Student const&) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x401B9F: Course::readStudentData(std::string) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x401836: Course::Course(std::string, std::string, std::string) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x4012F9: main (assign3.cpp:27)
==4223== 
==4223== Invalid read of size 8
==4223==    at 0x4EF15F1: std::string::assign(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==4223==    by 0x4023E6: Student::operator=(Student const&) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x401B9F: Course::readStudentData(std::string) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x401836: Course::Course(std::string, std::string, std::string) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x4012F9: main (assign3.cpp:27)
==4223==  Address 0x8050190f0 is not stack'd, malloc'd or (recently) free'd
==4223== 
==4223== 
==4223== Process terminating with default action of signal 11 (SIGSEGV)
==4223==  Access not within mapped region at address 0x8050190F0
==4223==    at 0x4EF15F1: std::string::assign(std::string const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==4223==    by 0x4023E6: Student::operator=(Student const&) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x401B9F: Course::readStudentData(std::string) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x401836: Course::Course(std::string, std::string, std::string) (in /home/ruslan/241Assign3/assign3)
==4223==    by 0x4012F9: main (assign3.cpp:27)

У меня есть еще один класс учеников, который был выполнен и был проверен для правильной работы, поэтому ошибка должна быть в курсе.

Файл заголовка курса:

#ifndef COURSE_H
#define COURSE_H

#include "student.h"

using std::string;

    class Course
    {
        private:
        string courseid;
        string courseName;
        Student Students[3][45];
        int enrolled[2];

        public:
        Course(); //default constructor
        Course(string, string, string); //alternate constructor 
        void readStudentData(string);
        void sortRow(int);
        void print();           

    };

#endif //COURSE.H

Определения ученического класса:

Student::Student()
{
    firstName = "None";
    lastName = "None";
    zid = "None";
}


Student::Student(string assignFirst, string assignLast, string assignZID)
{
    firstName = assignFirst;
    lastName = assignLast;
    zid = assignZID;
}



string Student::getLastName()
{
    return lastName;
}


void Student::print()
{
    cout << lastName << ", " << firstName << std::setw(15) << zid << endl; 
}
Теги:
class
object
oop
segmentation-fault

1 ответ

3
Лучший ответ

У вас есть неопределенное поведение в нескольких местах. Первый в Course конструкторах, где вы пишете для enrolled вне границ. Во-вторых, когда использование использует неинициализированное значение из этого массива как индекс для другого массива.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню