C ++基本动态分配

时间:2017-10-27 06:19:20

标签: c++ dynamic

在这个例子中,我不明白为什么无法动态分配列表的第一个元素。 我理解解决方案很糟糕,因为我将丢失指向“a”的指针,它将悬空。我不明白的是为什么在这种情况下我的函数返回一个空列表。

我按要求简化了示例:

ListNode* createList() {
    //Why not - ListNode* a = new ListNode(0); ?
    ListNode list(0); ListNode * a = &list;
    for(int i=0; i < 5; i++){
        a->next = new ListNode(0);
        a = a->next;
    }
    //return a->next;
    return list.next;
}

2 个答案:

答案 0 :(得分:1)

我修改了您的代码,以便动态分配第一个元素。

建议的解决方案存在的问题是,当 a 到达列表末尾时,它会将指针返回到列表的末尾(因此返回空列表)。

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if (l1 == NULL && l2 == NULL) return NULL;
int carry = 0, sum = 0;
ListNode* a = new ListNode(0);
ListNode* head = a;
while(l1 || l2 || carry){
    sum = carry;
    if (l1 != NULL) sum+=l1->val;
    if (l2 != NULL) sum+=l2->val;     
    carry = sum/10;
    a->next = new ListNode(sum % 10);
    a = a->next;
    l1 = (l1 == NULL) ? NULL : l1->next;
    l2 = (l2 == NULL) ? NULL : l2->next;
}
return head->next;

}

希望它有所帮助。

答案 1 :(得分:1)

返回a->next失败是因为

a = a->next;

在创建列表时遍历列表,因此a始终指向列表中的最后一个节点。完成构建列表后

return a->next;

a仍然是列表中的最后一个节点,next可能是NULLnullptr。如果它不是,你就会得到一个巨大的爆炸虫。没有返回列表,因为没有更多列表要返回,此时您已经丢失了列表的开头。糟糕!

另一方面,

return list.next; 

在您创建的虚拟占位符节点之后返回节点,这是您在虚拟节点上构建的列表。由于list是一个局部变量,因此它具有自动存储持续时间,并在超出范围时为您清理。它所指向的ListNode链都是动态分配的,可以安全返回。

附录:

在您删除的代码中,使用

动态分配a
ListNode* a = new ListNode(0);

表示在函数结束时a需要清理,如你所指出的那样,虽然这不是一个悬空指针,但它被称为泄漏。

你可以用

来挽救它
ListNode* a = new ListNode(0);
ListNode* start = a;

以后

return start->next;

但是使用list创建的自动版本不需要清理,是更好的选择,因为可能会出错。

更好的是,根本没有虚拟节点,只保留指向第一个创建节点的指针,但那是另一个时间的故事。