0

閉じたハッシュ テーブルを設定するプログラムがあります。ハッシュ テーブルの各要素には、さまざまなメンバー (名前、ID、年など) を保持する Student クラスがあります。アレイに追加されたものを印刷しようとしているだけですが、SegFault が発生し続け、その理由がわかりません。ただし、それは私の印刷機能だけです。コード行を他の関数にコピーしたり、別のクラスに配置したりしましたが、そこでは機能しますが、印刷機能から印刷しようとすると機能しません。私はロープの終わりにいて、各メンバーのメモリの場所にアクセスできる理由を理解しようとしていますが、実際の値ではありません。

これが私のプログラムです:

main.cpp:

using namespace std;
#include <cstdlib>
#include "hash.h"

int main()
{
string temp1;
string temp2;
string temp3;
string temp4;
string temp5;
string temp6;

Hash h;

do{
cout << "set> ";
cin >> temp1;

//Checking for quit command.

if(temp1.compare("quit") == 0)
{
    return 0;
}
 //checking for add command.
else if(temp1.compare("add") == 0)
{
    cin >> temp2;
    cin >> temp3;
    cin >> temp4;
    cin >> temp5;
    cin >> temp6;
    Student *s1 = new Student(temp2, temp3, temp4, temp5, temp6);
    Element e1(s1);
    h.add(e1);
}
//checking for remove command.
else if(temp1.compare("remove") == 0)
{
    int r;
    cin >> r;
    h.remove(r);
}
//checking for print command.
else if(temp1.compare("print") == 0)
{
    h.print();
}
//Anything else must be an error.
else
{
    cout << endl;
    cout << "Error! "<< endl;
}
}while(temp1.compare("quit") != 0);
}

ハッシュ.h:

#include <string>
#include <iostream>
#include <cstdlib>

using namespace std;

// Student Class
class Student{
private:
    string firstName;
    string lastName;
    string id;
    string year;
    string major;

public:

//Constructor
    Student(string a, string b, string c, string d, string e);
friend class Element;
friend class Hash;
};

//Element class
class Element{
    private:
            Student *data;
    public:
            int getKey();
    Student* getData();
    void printStudent();

//Constructor
           Element(Student *e)
    {
        data = e;
    };
friend class Hash;
};

class Hash{
private:
    Element **array;
public:
    void add(Element);
    void print();
    void remove(int);

//Constructor
    Hash()
    {
        array = new Element *[10];
    };
friend class Student;
};

ハッシュ.cpp:

#include "hash.h"

//The Constructor for Student
 Student::Student(string a, string b, string c, string d, string e)
{
firstName = a;
lastName = b;
id = c;
year = d;
major = e;

}

//getKey function for Element Class

int Element::getKey()
{
int key = atoi(getData()->id.c_str());
return key;
}

Student* Element::getData()
{
return data;
}

void Element::printStudent()
{
string c = data->firstName;
cout<< "(" << c << ")";
}

//The add command
void Hash::add(Element e1)
{
int x = e1.getKey()%10;
int i = 0;

if(array[x] == NULL || array[x]->getData() == NULL)
{
    array[x] = &e1;

}

else
{while(array[x] != NULL || array[x]->getData() != NULL)
{
    x=(x+(i*i))%10;
    if(array[x] == NULL || array[x]->getData() == NULL)
    {
        array[x] = &e1;
        break;
    }
    else
    {
        i++;
    }
}}

}

//The remove command
void Hash::remove(int n)
{
Element e2(NULL);
for(int j = 0; j<10; j++)
{
    if(n == array[j]->getKey())
    {
        array[j] = &e2;
        cout << "true" << endl;
        break;
    }
}
cout << "false" << endl;
}
//The Print command
void Hash::print()
{   int k = 0;
while(k<10)
{
    if(array[k] == NULL)
    {
        cout << "(NULL)";
    }
    else if(array[k]->getData() == NULL)
    {
        cout << "(DEL)";
    }
    else
    {
        cout << "(" << array[k]->getData()->firstName << ")";
    }
k++;
}
cout << endl;
}

ご協力ありがとうございました。

4

2 に答える 2

2

ぶら下がっているポインターがあります。

この関数は、 の一時コピーを取得しElement、 を呼び出しますe1

//The add command
void Hash::add(Element e1)
{

次に、このローカル変数のアドレスを格納します。

    array[x] = &e1;

Hash::addスコープを離れると、存在e1しなくなります。

}

array[x]は、もはや存在しないメモリを指していますElement e1

あなたが直面している一般的な問題は、Hashオブジェクトへのポインターを維持するクラスを設計したものの、それらのオブジェクトがいつ破棄されるかに関する制御や知識がほとんどないことです。

Hash少なくとも がそうする限り、最後に追加されたオブジェクトを個人的に確認する必要がありますHash

于 2013-02-23T17:34:54.410 に答える
0

問題の最も簡単な解決策は、 Element インスタンスをポインターではなく値で Hash に格納することです。そう:

class Hash{
private:
    Element *array;
public:
    void add(Element);
    void print();
    void remove(int);

//Constructor
    Hash()
    {
        array = new Element[10];
    };
friend class Student;
};

新しい要素を保存するか、既存のものを削除すると、それらがコピーされます。

array[x] = e1; // not &e1 anymore

これはあまり良い方法ではありませんが、少なくとも最小限の変更でプログラムを実行可能な状態に変更できます。

于 2013-02-23T17:42:33.413 に答える