Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的内存泄漏_C_Memory_Pointers - Fatal编程技术网

C语言中的内存泄漏

C语言中的内存泄漏,c,memory,pointers,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;

我是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中,我们使用MalCube()函数为数据结构分配内存空间,并且我记得使用新关键字“动态”在C++中分配内存。使用malloc()分配内存与使用new分配内存有什么区别?我的代码中确实存在内存泄漏吗?

在使用完由
malloc()分配的内存后,需要调用
free()

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

要进行比较,您需要使用
==

if (symp->next == 0) {
或者在没有明确比较的情况下进行:

if (!symp->next) {

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

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

if (symp->next = 0){
  symbolList.tail = previous;
  previous->next =0;
} else {
  previous->next = symp->next;
  symp->next = 0;
}
什么时候
symb->next
不是零?如果
symb
为空,则不会执行任何操作,因为head节点也将为null

令人困惑的是,您在第一个if(应该始终是这样)中将
previous
附加到
symb
,但在下一个if中,您将
symb
附加到
previous
。第二种情况有什么理由,在什么情况下会发生

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

正如前面指出的那样,
symb->next=0
可能只是一个输入错误,因为这永远都是正确的,而且是一个常见的错误。我开始做的是:
如果(0==symb->next)
,那么如果您执行了
0=symb->next
,则会出现编译器错误

更新:


正如在注释中指出的,此函数将始终转到'else'子句,这实际上可能是预期行为。

如上所述,如果(symp->next=0)
是赋值操作,并且if语句的计算结果将为false。因此,您不仅会丢失指向
symp
之后下一个表项的指针,而且还会丢失上一个->下一个指针(我假定它指向
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);
}

symb->next=0将始终计算false而不是true。你是对的,我没有考虑next设置为0后会发生什么。
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);
}