【问题标题】:Segment Fault 11 [closed]段故障 11 [关闭]
【发布时间】:2019-01-23 02:49:01
【问题描述】:

我收到段错误 11 的错误。它将通过 printall()command 运行,但似乎在 printInvalidEmail 命令时失败。

我还可以输入我创建的其他类。我有大约 6 个不同的类和这些类的头文件。我正在寻找从何处着手解决此错误。

/*
 * roster.cpp
 *
 *  Created on: Jan 9, 2019
 *      Author: kaylasiemon
 */
#include <string>
#include <iostream>
#include <vector>
#include <sstream>
#include "student.h"
#include "securityStudent.h"
#include "networkStudent.h"
#include "softwareStudent.h"
#include "degree.h"
#include "roster.h"

using namespace std;

roster::roster() {
}

roster::~roster() {
}

void roster::add(string studentID, string firstName, string lastName, string emailAddress, int age, int daysInCourse1, int daysInCourse2, int daysInCourse3, degree d){
    int courseDays[] = {daysInCourse1, daysInCourse2, daysInCourse3};
    if (d == degree::SECURITY)
        classRosterArray[iindex++] = new securityStudent(studentID, firstName, lastName, emailAddress, age, courseDays, d);

    if (d == degree::SOFTWARE)
        classRosterArray[iindex++] = new softwareStudent(studentID, firstName, lastName, emailAddress, age, courseDays, d);

    if (d == degree::NETWORK)
        classRosterArray[iindex++] = new networkStudent(studentID, firstName, lastName, emailAddress, age, courseDays, d);
}

void roster::remove(string studentID){
    bool removeStudent = false;
    for(int i = 0; i < 5; i++){
        if (classRosterArray[i] != NULL) {
            if(studentID == classRosterArray[i] ->getID()){
                classRosterArray[i] = nullptr;
                removeStudent = true;
            }
        }
    }
    if (removeStudent == false)
        cout << "Student ID invalid. No one to remove";
}

void roster::printAll(){
    cout << "Roster:" << endl;
    for (int i = 1; i < 6; i++)
        classRosterArray[i] -> print();
}

void roster::printByDegreeProgram(int degreeProgram){
    cout << "Displaying Roster by Degree Type:" << endl;
    degree deg1;
    if (degreeProgram == 0)
        deg1 = degree::SECURITY;
    if (degreeProgram == 1)
        deg1 = degree::NETWORK;
    if (degreeProgram == 2)
        deg1 = degree::SOFTWARE;
    for (int i = 1; i < 6; i++){
        if (deg1 == classRosterArray[i]->getDegreeProgram())
            classRosterArray[i] -> print();
    }
}

void roster::printDaysInCourse(string studentID){
    int average;
    for (int i = 1; i < 6; i++){
        if (classRosterArray[i] ->getID() == studentID){
            average = (classRosterArray[i]->getCourseDays()[0] + classRosterArray[i]->getCourseDays()[1] + classRosterArray[i]->getCourseDays()[2]) / 3;
            cout << average << endl;
        }
    }
}

void roster::printInvalidEmails(){
    cout << "invalid email addresses:" << endl;
    for (int i = 0; i < 5; i++){
        bool atSign = false;
        bool space = false;
        bool period = false;
        string email;
        email = classRosterArray[i] ->getemail();
        for (char &letter:email){
            if (letter == '@')
                atSign = true;
            if (letter == ' ')
                space = true;
            if (letter == '.')
                period = true;
        }
        if (atSign == false || space == false || period == false)
            cout << classRosterArray[i] ->getemail() << endl;
    }
}

int main(){
    const string studentData[] ={   "A1,John,Smith,John1989@gm ail.com,20,30,35,40,SECURITY",
                                    "A2,Suzan,Erickson,Erickson_1990@gmailcom,19,50,30,40,NETWORK",
                                    "A3,Jack,Napoli,The_lawyer99yahoo.com,19,20,40,33,SOFTWARE",
                                    "A4,Erin,Black,Erin.black@comcast.net,22,50,58,40,SECURITY",
                                    "A5,Kayla,Siemon,ksiemon@wgu.edu,24,30,33,29,SOFTWARE"};

    roster classRoster;

    cout << "Scripting and Programming - Applications – C867" << endl << "Kayla Siemon" << endl <<"#000736769" << endl;
    degree degreepath;
    for (int i = 0; i < 5; i++){
        stringstream studentlist(studentData[i]);
        vector<string> results;

        while(studentlist.good()){
            string temp;
            getline(studentlist, temp, ',');
            results.push_back(temp);
        }
        if (results[8] == "SECURITY")
            degreepath = degree::SECURITY;
        if (results[8] == "NETWORK")
            degreepath = degree::NETWORK;
        if (results[8] == "SOFTWARE")
            degreepath = degree::SOFTWARE;
        classRoster.add(results[0], results[1], results[2], results[3], stoi(results[4]), stoi(results[5]), stoi(results[6]), stoi(results[7]), degreepath);
    }
    classRoster.printAll();
    classRoster.printInvalidEmails();
        classRoster.printDaysInCourse("A1");
    classRoster.printByDegreeProgram(SOFTWARE);
    classRoster.remove("A3");
    classRoster.remove("A3");

     return 0;
}

【问题讨论】:

  • using namespace std; 在头文件中是一个非常糟糕的主意
  • 我发布的文件是源文件。即 StudentRoster.cpp
  • 您在使用调试器时发现了什么?
  • 您的阵列有多大?看起来您引用的行是一个至少需要 6 个元素的循环,而您的其余代码似乎假设 5 个元素。您是否正在阅读数组末尾的内容?

标签: c++ segmentation-fault cppcheck


【解决方案1】:

这是发展调试技能的好机会。您要做的第一件事是确定准确是哪行代码触发了崩溃。您可以使用调试器(通过单步执行代码)来完成此操作,或者如果您愿意,也可以手动检测您的代码。例如,如果您认为崩溃发生在 printInvalidEmail() 方法中,您可以通过临时将调试输出行添加到方法中,将其缩小到特定行,如下所示:

void roster::printInvalidEmails(){
    cout << "invalid email addresses:" << endl;
    for (int i = 0; i < 5; i++){
cout << "X1 " << i << endl;
        bool atSign = false;
        bool space = false;
        bool period = false;
cout << "X2 " << endl;
        string email;
cout << "X3 " << endl;
        email = classRosterArray[i] ->getemail();
cout << "X4 " << endl;
        for (char &letter:email){
cout << "X5 " << letter << endl;
            if (letter == '@')
                atSign = true;
            if (letter == ' ')
                space = true;
            if (letter == '.')
                period = true;
        }
cout << "X6" << endl;
        if (atSign == false || space == false || period == false)
        {
cout << "X7" << endl;
            cout << classRosterArray[i] ->getemail() << endl;
        }
cout << "X8" << endl;
    }
cout << "X9" << endl;
}

请注意,我插入了很多行,例如cout &lt;&lt; "X1" &lt;&lt; endl;,每行都打印一个唯一的字符串,因此我可以轻松地将它们区分开来。现在当你运行你的程序时,你会得到更多的输出,但主要看的是你的程序输出的最后一行文本,就在它崩溃之前——导致崩溃的代码可能直接在它之后输出该文本的行。

找到该行,它会(希望)让您了解为什么该行可能会崩溃 - 例如,如果您看到的最后一行文本输出是“X3”,而您没有看到“ X4" 之后打印,那么您可以非常确定 email = classRosterArray[i]-&gt;getemail(); 行导致了崩溃......并且可能的原因是 classRosterArray[i] 是一个 NULL 或其他无效指针(因此当您尝试取消引用它以调用getemail()) - 然后您需要追踪在classRosterArray 中设置条目的各个位置,以找出它们没有正确设置的原因。 (或者,也可能是 getmail() 方法内部存在错误,并且程序在其中崩溃 - 在这种情况下,您可以在该方法中添加更多调试输出以确定位置和原因)

一旦您找出导致崩溃的原因并修复它,您就可以返回并再次删除所有临时调试输出行。 (请注意,我故意将所有临时的 cout 调用不缩进,这样它们就可以清楚地从“真实”代码中突出出来,并且在您完成调试后很容易返回并快速删除它们)

【讨论】:

    猜你喜欢
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 1970-01-01
    相关资源
    最近更新 更多