我有一个程序,我正在设置一个封闭的哈希表。在Hash表的每个Element中,都有一个Student类,它包含不同的成员(名称,id,年份等)。我只是想打印出已添加到我的阵列中的内容,但我一直在使用SegFault,我不知道为什么。不过,这只是在我的打印功能中。我已经将代码行复制到我的其他函数中或者将它们放在不同的类中,它们在那里工作,但是当我尝试从我的print函数打印时却没有。我在绳子的尽头,试图弄清楚为什么我可以访问每个成员的记忆位置,但不是它的实际价值。
这是我的计划:
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);
}
hash.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;
};
hash.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;
}
感谢您的帮助。
答案 0 :(得分:2)
此函数获取Element
的临时副本,并将其称为e1
。
//The add command
void Hash::add(Element e1)
{
然后存储此local variable的地址。
array[x] = &e1;
当Hash::add
离开范围时,e1
不再存在。
}
array[x]
现在指向的内存不再是Element e1
。
您面临的一般问题是您设计了一个Hash
类来维护指向对象的指针,但对这些对象何时被销毁几乎无法控制或了解。
您需要亲自确保添加到Hash
的对象至少与Hash
一样长。
答案 1 :(得分:0)
对于您的问题,最简单的解决方案可能是通过值而不是指针来存储Hash中的Element实例。所以:
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
这不是一个很好的做法,但至少可以在一些可行的状态下改变你的程序,只需要很少的改动。