stack around the variable 'BDMonth' was corrupted

Существует класс Student:

Выдержка из Student.h:

class Student {
    private:
        Name name;
        Date BDate;
        University university;
        SEX sex;

        Semester* semesters[9];

    public:
        Student(string SName, string FName, string TName, Date BDate, unsigned short receiptYear, string faculty,\
        string department, string group, string IDCard, SEX sex
                );

        Student();

        ~Student();

Выдержка из Student.cpp:

Student::Student() {
    string SName, FName, TName, faculty, department, group, IDCard, sexString;
    Date BDate;
    unsigned short BDDay, BDMonth, BDYear, receiptYear;
    SEX sex;

    cout << endl << "Now you're going to add student in database. Follow the instructions below to continue! " << endl;

    cout << "Enter student's second name: " << endl;
    cin >> SName;
    cout << "Enter student's first name: " << endl;
    cin >> FName;
    cout << "Enter student's third name: " << endl;
    cin >> TName;

    bool flag = true;
    while (flag) {
        cout << "Enter student's birthdate (DD.MM.YYYY): " << endl;
        scanf_s("%hu.%hu.%hu", &BDDay, &BDMonth, &BDYear);
        bool leap_year = BDYear % 100 ? !(BDYear % 4) : !(BDYear % 400);
        if (
                ((BDMonth == 4 || BDMonth == 6 || BDMonth == 9 || BDMonth == 11) && BDDay > 30)
                || ((BDMonth == 2) && leap_year && BDDay > 29)
                || ((BDMonth == 2) && !leap_year && BDDay > 28)
                || (BDDay > 31)
                || (BDMonth > 12)
                || !(BDDay || BDMonth)
           ){
            cout << "ERROR! You've entered wrong birthdate. Try again!" << endl;
        }
        else
            flag = false;
    }

    BDate = {BDDay, BDMonth, BDYear};

    flag = true;
    while (flag){
        cout << "Enter student's receipt year: " << endl;
        cin >> receiptYear;
        if (receiptYear - BDYear < 14)
            cout << "ERROR! Student on receipt must be 14 years old or older. Try again!" << endl;
        else
            flag = false;
    }

    cout << "Enter student's faculty: " << endl;
    cin.get();
    getline(cin, faculty);
    cout << "Enter student's department: " << endl;
    getline(cin, department);
    cout << "Enter student's group: " << endl;
    cin >> group;
    cout << "Enter student's ID (ID Card): " << endl;
    cin >> IDCard;

    flag = true;
    while (flag){
        cout << "Enter student's sex: " << endl;
        cin >> sexString;
        if (stringToSEX(sexString) == Undefined)
            cout << "ERROR! Unknown sex. It must be \"Male\" or \"Female\". Try Again!" << endl;
        else
            flag = false;
    }

    sex = stringToSEX(sexString);


    name = {move(SName), move(FName), move(TName)};
    this->BDate = BDate;
    university = {receiptYear, move(faculty), move(department), move(group), move(IDCard)};
    this->sex = sex;
    for (auto & semester : semesters)
        semester = nullptr;

    cout << "You've just successfully added " << name.Second << " " << name.First << " " << name.Third << " to the list of students" << endl;
}

Выдержка из файла, описывающего структуры, перечисления и функции, использованные выше:

struct Name{
    string Second;
    string First;
    string Third;
};

struct Date{
    unsigned short day;
    unsigned short  month;
    unsigned short year;
};

struct University {
    unsigned short receiptYear;
    string faculty;
    string department;
    string group;
    string IDCard;
};

enum SEX {
    Undefined = -1,
    Male,
    Female
};

enum GRADE{
    GREAT = 5,
    GOOD = 4,
    SATISFACTORY = 3,
    COMPLETE = 6,
    INCOMPLETE = 2,
    UNSET = 0
};

string GRADEToString(GRADE grade) {
    switch (grade) {
        case 0: return "UNSET";
        case 2: return "INCOMPLETE (2)";
        case 3: return "SATISFACTORY (3)";
        case 4: return "GOOD (4)";
        case 5: return "GREAT (5)";
        case 6: return "COMPLETE";
        default: return "Error displaying the grade";
    }
}

string SEXToString (SEX sex) {
    switch (sex) {
        case 0: return "Male";
        case 1: return "Female";
        default: return "Error displaying the sex";
    }
}

SEX stringToSEX (const string& sex) {
    if (sex == "Male" or sex == "male")
        return Male;
    else if (sex == "Female" or sex == "female")
        return Female;
    else
        return Undefined;
}

Выдержка из main.cpp

    auto *John = new Student();
    +*John; // Здесь был переопределён оператор, который проверенно работает, но не суть, ибо до сюда программа даже не доходит
    John->printInfo();

    delete John;

Проблема: В самом конце выполнения конструктора (даже после отработки последнего cout об успешном создании объекта), описанного выше, компилятор выдаёт ошибку:

Скрин ввода

Дебаггер настойчиво говорит, что он застрял на закрывающей скобке конструктора. При запуске без дебаггера вместо последней строки выдаёт это окно: Скрин окна

После этого при нажатии на "Abort" выдаёт: "Process finished with exit code 3". При игнорировании продолжает работу и ругается ещё и на BDDay, после чего проделывает все последующие инструкции - работает с этим объектом, выводит информацию, благополучно его удаляет и завершается с кодом 0: Ignore

UPD 1: Чуть позже в scanf_s("%d.%d.%d", &BDDay, &BDMonth, &BDYear); %d был заменён на %u, но проблему это не решило. Новая ошибка: Новая ошибка

UPD 2: В scanf_s("%u.%u.%u", &BDDay, &BDMonth, &BDYear); %u был заменён на %hu, но проблему это не решило.


Ответы (1 шт):

Автор решения: onlikerop

Проблема решилась удалением строки со scanf_s, заменой её на прямое указание значений переменных, пересборкой проекта и заменой прямого указания значений на абсолютно идентичную изначальной строку с функцией scanf_s...

→ Ссылка