prevent memory leak c++
本问题已经有最佳答案,请猛点这里访问。
如何防止下面代码中的内存泄漏?我在返回语句之前添加了"删除sentinel"。但是如何处理这两条线
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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; } }; |
你的代码真的很混乱…不是因为算法很复杂,而是因为您使用了多个变量来指向同一个对象。为什么有这么多未使用的变量?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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++中经常出现的一个主题。
1 2 3 4 5 6 7 8 9 10 11 | 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; } } |
有一个简单的答案-当前代码有一个泄漏-sentinel,所有其他分配的节点都不会泄漏-因为它们仍然可以通过返回的pointer sentinel->next访问
所以修复漏洞的简短版本将会改变
1 | return sentinel->next; |
具有
1 2 3 | d = sentinel->next; delete sentinel; return d; |
较长的版本需要将原始指针的用法更改为智能指针
实际上,正如事后所想,更理想的解决方案是使用std::forward_列表而不是自制列表。
不要使用原始指针。请参阅C++核心指南(C++中最重要的一些领导者的最新指南)。