我正在练习c ++的新/删除,哈希函数和链接。
我自己做了一次练习。
我有一个结构
typedef struct student
{
int id;
string fName;
string lName;
student * nextStudent;
}Student;
然后在main函数中,我定义了一个学生数组
Student * table = new Student [10];
我有自己的哈希函数,它接受id,并改为0-9。 我想添加一个我跟随的学生
void addStudent(int studentId, string firstName, string lastName, Student *table)
{
// using hash function, convert the id into hashed id
int hashedID = hashFunction( studentId );
Student * pointer = &table[hashedID];
while(pointer->nextStudent !=NULL){
pointer = pointer->nextStudent;
}
// once we reach to the student who has NULL in nextStudent
// add student
Student *tmp = new Student;
tmp->id = studentId;
tmp->fName = firstName;
tmp->lName = lastName;
tmp->nextStudent = NULL;
// link
pointer->nextStudent = tmp;
}
我测试过,看起来很好。
问题是删除。 由于学生变量存储在动态记忆中, 我需要使用删除。
以下是我的代码。
void deleteAll(Student *table, int len)
{
for (int i = 0; i < len; i++)
{
Student* tmp = &table[i];
// delete student info except the last one
while ( tmp -> nextStudent !=NULL){
Student* tmp2;
tmp2 = tmp;
tmp = tmp->nextStudent;
delete tmp2;
}
}
}
我拜访了每个学生varialbes并做了删除。 我在删除功能中找不到任何问题...
这是我跑完后得到的......
malloc: *** error for object 0x7f85f1404b18: pointer being freed was not allocated
我不知道我做错了什么.. 你能救我吗?
修改...
正如你们所说的那样 我添加了#34;删除[]表&#34;在主要功能.. 另外,我删除&#34;删除tmp&#34;在deleteAll函数中;我认为&#34;删除[]表&#34;将处理该部分。
仍然不起作用..
顺便说一句,我忘了在初始帖子中添加initTable函数。 initTable初始化表...
void initTable (Student *table, int len)
{
for (int i = 0; i < len; ++i)
{
table[i].nextStudent = NULL;
}
}
谢谢。
答案 0 :(得分:2)
永远不会初始化nextStudent
字段,因此此处创建的所有10个元素都指向未知值。
Student * table = new Student [10];
这导致addStudent
循环,直到某些pointer->nextStudent
偶然遇到NULL值,然后覆盖它不拥有的内存(除非它在第一次迭代时遇到幸运NULL)。 / p>
while(pointer->nextStudent !=NULL) { ... }
学生`结构(顺便说一下,为什么typedef?)应该有一个构造函数来至少这样做。
student::student() : nextStudent(NULL) { }
[编辑] @JonathanPotter在评论中正确指出的另一个问题是,10个student
列表中每个列表的头部都是table
数组的成员。 不是动态分配的,不应单独删除。
qucik / easy修复程序将添加student
析构函数以递归方式删除子节点:
student::~student() { if(nextStudent) delete nextStudent; }
然后deleteAll
会缩减为:
void deleteAll(student *table, int len)
{
for (int i = 0; i < len; i++)
{
student *tmp = &table[i];
if(tmp->nextStudent) delete tmp->nextStudent;
}
// this leaves the dynamically allocated table[] in place
// to delete it as well, just `delete [] table;`
}
但是,一旦列表变大,这样的递归可能变得不切实际,并且应该更好地重写为迭代(没有递归析构函数)。
student::~student() { }
// ...
void deleteAll(student *table, int len)
{
for(int i = 0; i < len; i++)
{
student *tmp = &table[i];
// delete student info except the *first* one
for(student *tmp2; tmp2 = tmp->nextStudent; )
{
tmp->nextStudent = tmp2->nextStudent;
delete tmp2;
}
}
// this leaves the dynamically allocated table[] in place
// to delete it as well, just `delete [] table;`
}
答案 1 :(得分:0)
然后在main函数中,我定义了一个学生数组
学生*表=新学生[10];
首先,您要创建Student而不是Student *的数组。你最近试图删除未分配的值。这就是你的程序行为的原因。
要创建指针数组Student *的指针,您需要以下内容:
Student** table = new Student*[10];
将函数参数从Student* table
更改为Student** table
并继续研究。
另外,请不要忘记使用delete[] table;
删除表格
祝你好运。