简体   繁体   English

C中的内存泄漏

[英]Memory Leak in C

I am a C beginner, and I am writing a very simple linked-list. 我是C语言的初学者,我正在写一个非常简单的链表。 I am wondering if there would be a memory leak in the following code: 我想知道以下代码是否会发生内存泄漏:

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

I am pretty sure if the pointer symp is not stored in another variable, there's no way of accessing the list entry that was pointed by the pointer, thus I will have a memory leak. 我很确定,如果指针symp没有存储在另一个变量中,则无法访问指针所指向的列表项,因此会发生内存泄漏。 In C, we use malloc() function to allocate memory space for a data structure, and I remember using new keyword to "dynamically" allocate memory in C++. 在C语言中,我们使用malloc()函数为数据结构分配内存空间,我记得在C ++中使用new关键字“动态”分配内存。 What are the differences between allocating memory using malloc() and using new? 使用malloc()和new分配内存之间有什么区别? Is there indeed a memory leak in my code? 我的代码中确实存在内存泄漏吗?

if (symp->next = 0) {

This if-"condition" is an assignment, setting symp->next to 0 . 这个if-“ condition”是一个赋值,将symp->next设置为0 If a pointer to another object was stored in symp->next , that object is lost and the objects memory will not be freed. 如果指向另一个对象的指针存储在symp->next ,则该对象将丢失,并且对象的内存将不会被释放。

For a comparision you need to use == instead: 为了进行比较,您需要使用==代替:

if (symp->next == 0) {

or do it without an explicit comparision: 或在没有明确比较的情况下执行此操作:

if (!symp->next) {

In the else case you remove symp from the list (assuming previous actually contains the element before symp ), but you don't free it's memory. else情况下,您可以从列表中删除symp (假设previous实际上包含了symp之前的元素),但是您不释放它的内存。 This might be a memory leak, but it depends on the code calling the function: That code might still free symp or do something else with the removed element, or it might just forget about it and leak it's memory. 这可能是内存泄漏,但是取决于调用该函数的代码:该代码可能仍然释放symp或对移除的元素执行其他操作,或者可能只是忘记了它而泄漏了它的内存。

使用完malloc()分配的malloc()后,需要调用free() malloc()

I am curious about what is supposed to be happening in your code: 我对您的代码中应该发生的事情感到好奇:

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

When would symb->next not be zero? 什么时候symb->next不为零? You aren't doing anything if symb is empty as the head node would also be null. 如果symb为空,则您什么也不做,因为头节点也为null。

The confusing part is that you are appending previous to symb in the first if (which should always be the case) but in the next one you are appending symb to previous . 混乱的部分是要附加previoussymb第一,如果(这应该总是这样),但在接下来的一个要附加symbprevious What rationale is there for this second one, and in what case will it ever happen? 第二个理由是什么,在什么情况下会发生?

As others have mentioned, if you allocate memory you need to free it, else you have a memory leak, as there is no garbage collector in C/C++, so every node that is going to be freed needs to be deallocated. 正如其他人提到的,如果分配内存,则需要释放它,否则会发生内存泄漏,因为C / C ++中没有垃圾回收器,因此需要释放的每个节点都必须被释放。

The symb->next = 0 is probably just a typo, as was pointed out, as that will always be true, and is a frequent bug. 正如指出的那样, symb->next = 0可能只是一个错字,因为这永远是正确的,并且是一个经常发生的错误。 What I started to do to help catch this is to do: if (0 == symb->next) , so if you did 0=symb->next then you will get a compiler error. 我开始做的工作是帮助您做到这一点: if (0 == symb->next) ,因此,如果您执行0=symb->next ,则会出现编译器错误。

UPDATE: 更新:

As was pointed out in a comment, this function will always go to the 'else' clause, which may be expected behavior, actually. 正如评论中指出的那样,此函数将始终转到“ else”子句,实际上这可能是预期的行为。

As pointed out above if(symp->next = 0) is an assignment operation and the if statement will evaluate to false. 如上所述, if(symp->next = 0)是赋值操作,并且if语句的计算结果为false。 Because of this you will not only lose the pointer to the next table entry after symp , but you also lose the previous->next pointer (which I assume points to symp anyway?). 因此,您不仅会丢失指向symp之后的下一个表条目的指针,而且还会丢失先前的-> next指针(无论如何我还是认为指向symp ?)。

Just a matter of style, but personally I would rewrite the function to be more like this: 只是样式问题,但是我个人会重写该函数,使其更像这样:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM