Valgrind:16字节块内8个字节已被释放。

4

我正在为课堂实验编写代码,这是一个使用循环链表进行OOD设计练习的过程。这意味着一些关键函数对我不可用。然而,我大部分困惑的原因是尽管我的驱动程序模仿了教授编写的驱动程序,但我仍然在标题中收到mchk错误。以下是它引用的代码:

{
int nNodesFreed{0};
node* n{head};

for(; n!= head || ! nNodesFreed; n = n->next) {
    delete n;
    nNodesFreed++;
    }
cout << "# nodes freed: " << nNodesFreed << endl;
}

我在一个类似的问题中看到,问题可能是我试图访问已经被释放的内存。例如,如果n不存在了,如何使n = n->next。我尝试使用当前指针和下一个指针切换到while循环,但这只会使问题变得更糟。在我的教授版本的作业中,代码可以完美地工作,但我还没有实现所需的函数。

我收到的确切错误是:

Invalid read of size 8 
  at 0x400D8A: main (lab04.cpp:28) // this references the for loop
Address 0x5a02048 is 8 bytes inside a block of size 16 free'd
  at 0x4C28FAC: operator delete(void*) 
  by 0x400D81: main (lab04.cpp:29)

感谢任何帮助。

2
“delete n” 然后 “n = n->next”??? - barak manos
然而,在没有我实现的函数版本的任务中,它完全可以工作。 - FutureShocked
1
未定义行为 - 它可能工作,也可能失败。 - barak manos
@FutureShocked 这就是有bug的代码的问题所在——它不会按照你的期望去执行。修复这些bug,那么这些谜团也会消失。 - David Schwartz
1
@FutureShocked,很简单——在你delete一个对象之后不要再访问它。你的代码就是这样做的,这就是问题所在。这可能会导致不可预测的行为。 - David Schwartz
显示剩余3条评论
1个回答

5
您在访问已被删除的 n,这会导致未定义的行为。
此外,您没有检查 n->next 是否有效:您在第一次迭代中删除了 head。删除 n 是否会更新 head?如果不是,则当您到达链表末尾时,您将再次遇到未定义的行为(这可能是由于 delete 一个 nullptr 或者 delete 一个垃圾指针(取决于链接列表结尾处的 n->next 指向什么)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接