如何防止以下代码中的内存泄漏?我添加了#34;删除哨兵"在返回声明之前。但是如何处理这两行d->next = new ListNode(sum % 10)
和d->next = new ListNode(1)
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* c1 = l1;
ListNode* c2 = l2;
ListNode* sentinel = new ListNode(0);
ListNode* d = sentinel;
int sum = 0;
while(c1 != NULL || c2 != NULL) {
sum /=10;
if(c1 != NULL){
sum += c1->val;
c1 = c1->next;
}
if(c2!= NULL){
sum += c2->val;
c2 = c2->next;
}
d->next = new ListNode(sum % 10);
d = d->next;
}
if(sum /10 == 1){
d->next = new ListNode(1);
}
return sentinel->next;
}
};
答案 0 :(得分:1)
有一个简单的答案 - 当前代码有一个泄漏 - sentinel,所有其他分配的节点都没有泄露 - 因为它们仍然可以通过返回的指针sentinel-> next
来访问修复泄漏的简短版本将是改变
return sentinel->next;
与
d = sentinel->next;
delete sentinel;
return d;
更长的版本需要将原始指针的使用更改为智能指针std::unique_ptr
,在这种情况下看起来像选择的指针。但是这应该对整个程序不仅仅是一个功能。
实际上 - 作为事后的想法 - 更理想的解决方案是使用std::forward_list而不是自制列表
答案 1 :(得分:1)
你的代码真的很混乱......不是因为算法很复杂,而是因为你使用了几个变量来指向同一个东西。为什么这么多未使用的变量?
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2)
{
ListNode* sentinel = new ListNode(0);
listNode* d = sentinel;
int sum = 0;
while (l1 != NULL || l2 != NULL) // use pointers l1 and l2, since passed by value.
{
if (l1 != NULL)
{
sum += l1->val;
l1 = l1->next;
}
if (l2 != NULL)
{
sum += l2->val;
l2 = l2->next;
}
d->next = new ListNode(sum % 10);
sum /= 10;
d = d->next;
}
if (sum)
{
d->next = new ListNode(sum);
}
// And this is where one of your memory leaks was...
if (sentinel->next)
{
d = sentinel->next; // delete useless sentinel.
sentinel->next = NULL; // important ! see ~ListNode()
delete sentinel;
sentinel = d;
}
return sentinel; // and not result->next.
}
为了避免从列表中泄漏,您需要编写一个正确的列表析构函数来释放子节点和其他相关资源(如果有)。这是c ++中一个相当反复出现的主题。
ListNode::~ListNode()
{
// never destroy lists recursively !! Destroying a large list
// that way could bust the stack, hence this odd looking loop.
for (ListNode * p = next, * q = NULL; p != NULL; p = q)
{
q = p->next;
p->next = NULL; // <-- avoids recursion.
delete p;
}
}
答案 2 :(得分:0)
不要使用原始指针。请参阅C++ Core Guidelines(C ++中一些最重要的领导者的最新指南)。