C中的内存泄漏

时间:2009-11-27 02:19:45

标签: c memory pointers

我是C初学者,我正在编写一个非常简单的链表。我想知道以下代码中是否会出现内存泄漏:

void removeListEntry(struct tableEntry *symp, struct tableEntry *previous) {
  if (symp->next = 0){
    symbolList.tail = previous;
    previous->next =0;
  } else {
    previous->next = symp->next;
    symp->next = 0;
  }
}

我很确定如果指针symp没有存储在另一个变量中,则无法访问指针指向的列表条目,因此我将发生内存泄漏。 在C中,我们使用malloc()函数为数据结构分配内存空间,我记得使用new关键字在C ++中“动态”分配内存。使用malloc()和使用new分配内存有什么区别?我的代码中确实存在内存泄漏吗?

4 个答案:

答案 0 :(得分:5)

if (symp->next = 0) {

此if-“条件”是一项分配,将symp->next设置为0。如果指向另一个对象的指针存储在symp->next中,则该对象将丢失,并且不会释放对象内存。

对于比较,您需要使用==代替:

if (symp->next == 0) {

或者在没有明确比较的情况下这样做:

if (!symp->next) {

else情况下,您从列表中删除symp(假设previous实际上包含symp之前的元素),但您没有释放它的内存。这可能是内存泄漏,但它取决于调用函数的代码:该代码可能仍然可以释放symp或对删除的元素执行其他操作,或者它可能只是忘记它并泄漏它的内存。

答案 1 :(得分:1)

完成free()分配的内存后,您需要致电malloc()

答案 2 :(得分:1)

我很好奇你的代码应该发生什么:

if (symp->next = 0){
  symbolList.tail = previous;
  previous->next =0;
} else {
  previous->next = symp->next;
  symp->next = 0;
}

symb->next何时不为零?如果symb为空,则您没有做任何事情,因为头节点也将为空。

令人困惑的部分是,您将previous追加到symb的第一个if(应该始终如此),但在下一个中,您将symb追加到{{ 1}}。第二个是什么理由,在什么情况下会发生?

正如其他人所提到的,如果你分配内存需要释放它,否则就会有内存泄漏,因为C / C ++中没有垃圾收集器,所以每个要释放的节点都需要被释放。

previous可能只是一个错字,正如所指出的那样,因为这将永远是真的,并且是一个常见的错误。我开始做的是帮助抓住这个: symb->next = 0,所以如果你if (0 == symb->next),那么你会遇到编译错误。

<强>更新

正如评论中所指出的,这个函数总是会转到'else'子句,实际上可能是预期的行为。

答案 3 :(得分:0)

如上所述,if(symp->next = 0)是赋值操作,if语句将计算为false。因此,您不仅会在symp之后丢失指向下一个表条目的指针,而且还会丢失之前的&gt;下一个指针(我假设它指向symp?)。

只是风格问题,但我个人认为函数更像是这样:

void removeNextListEntry(struct tableEntry *previous) {
  struct tableEntry *dummy = previous->next;
  if (dummy->next == 0){
    symbolList.tail = previous;
    previous->next =0;
  } else {
    previous->next = dummy->next;
  }
  free(dummy);
}