【问题标题】:c++ pointer being freed was not allocated errorc++指针被释放没有分配错误
【发布时间】:2015-11-20 05:42:23
【问题描述】:

我正在练习c++的new/delete、hashfunction和linked。

我自己做了一个练习。

我有一个结构是

typedef struct student
{
    int id;
    string fName;
    string lName;
    student * nextStudent;
}Student; 

然后在主函数中,我定义了一个学生数组

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;
         }
    }
}

我访问了每个学生变量并进行删除。 我在删除功能中找不到任何问题...

这是我跑步后得到的..

malloc: *** error for object 0x7f85f1404b18: pointer being freed was not allocated

我不知道我做错了什么.. 你能帮帮我吗?

编辑...

正如你们所说 我在主要功能中添加了“删除[]表”.. 另外,我删除了 deleteAll 函数中的“delete tmp”;我认为“删除 [] 表”将处理该部分。

还是不行..

顺便说一句,我忘了在最初的帖子中添加 initTable 函数。 initTable 初始化表...

void initTable (Student *table, int len)
{
    for (int i = 0; i < len; ++i)
    {
        table[i].nextStudent = NULL;
    }
}

谢谢。

【问题讨论】:

  • table分配后如何初始化?
  • table[i] 不是单独分配的,它是作为数组的一部分分配的。链表中的所有后续学生都可以用delete删除,但table[i]只能通过删除整个数组(delete[] table;)来删除。
  • @JonathanPotter 应该写成答案
  • @JonathanPotter 我编辑了我的帖子以涵盖您非常有效的观点,但我在初读时忽略了这一点。如果您认为我“借”得太多,请告诉我,因为那不是我的本意。
  • @dxiv 很好,事实上 +1 是为了花时间回答。

标签: c++ pointers


【解决方案1】:

nextStudent 字段从未初始化,因此此处创建的所有 10 个元素都指向未知值。

Student * table = new Student [10];

这会导致 addStudent 循环,直到某些 pointer-&gt;nextStudent 偶然命中 NULL 值,然后覆盖它不拥有的内存(除非它在第一次迭代中命中幸运 NULL)。

while(pointer->nextStudent !=NULL) { ... }

“student”结构(顺便说一句,为什么是 typedef?)至少应该有一个构造函数来做到这一点。

student::student() : nextStudent(NULL) { }


[ 编辑] @JonathanPotter 在评论中适当指出的另一个问题是,10 个student 列表中的每一个的头部都是table 数组的成员。它是动态分配的,应该单独删除。

快速/简单的解决方法是添加一个 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;`
}

【讨论】:

    【解决方案2】:

    然后在主函数中,我定义了一个学生数组

    学生 * 表 = 新学生 [10];

    首先,您正在创建学生数组而不是学生*。迟到你试图删除未分配的值。这是您的程序行为的原因。

    要创建指针数组的指针 Student* 您需要以下内容:

    Student** table =  new Student*[10];
    

    将您的函数参数从 Student* table 更改为 Student** table 并继续研究。 也不要忘记使用delete[] table; 删除表 祝你好运。

    【讨论】:

      猜你喜欢
      • 2013-11-02
      • 2014-06-07
      • 1970-01-01
      • 2015-10-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-12
      • 2012-04-16
      • 1970-01-01
      相关资源
      最近更新 更多