我是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分配内存有什么区别?我的代码中确实存在内存泄漏吗?
答案 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);
}