删除后可以使用指针吗?

时间:2015-08-15 08:40:33

标签: c++ pointers

问题是从排序列表中删除重复项,代码为:

if subtotal < minval then DO THIS else DO THIS

代码是对的,我的谜题是:

指针&#34; cur&#34; ,&#34;删除&#34; ,使用&#34; CUR&#34;和&#34; cur = cur-&gt; next&#34; in&#34; for&#34;。为什么没事?

很抱歉麻烦,leetcode会给代码提供AC,所以我怀疑自己感谢答案。

5 个答案:

答案 0 :(得分:3)

首先澄清:指针是指向到内存区域的东西。

如果你在指针上调用delete,你将释放指针指向的任何内容,但不会破坏指针本身。您可以重复使用该指针,但在删除它之后再次取消引用它未定义的行为,因为没有任何保证它用来指向的内存仍然可供您使用。

之后,您的代码会导致UB
delete cur;

你用cur = cur->next取消引用该指针。您无法保证cur仍然指向next具有实际含义作为地址的有效内存区域。

您的代码的正确版本如下:

ListNode* deleteDuplicates(ListNode* head) {
  if (head == NULL) return NULL;
  for (ListNode* prev = head, *cur = head->next; prev->next; cur = prev->next)
  {
    if (prev->val == cur->val)
    {
      prev->next = cur->next;
      delete cur;
    }
    else
    {
      prev = cur;
    }
  }
  return head;
}

Live Example

答案 1 :(得分:1)

不,不行。它只是undefined behaviour,一切皆有可能。在这种情况下,指针指向的内容不会被清除,但你不能也不应该依赖它。

答案 2 :(得分:0)

该函数具有未定义的行为。删除后,您可能无法访问该对象。

所以这个循环

        for (ListNode* prev = head, *cur = head->next; cur; cur = cur->next)
        {
            if (prev->val == cur->val)
            {
                prev->next = cur ->next;
                delete cur;
            }
        //...

错了。

该功能可以通过以下方式定义

ListNode* deleteDuplicates( ListNode *head ) 
{
    if ( head )
    {        
        for ( ListNode *current = head; current->next; )
        {
            if ( current->val == current->next->val )
            {
                ListNode *tmp = current->next;
                current->next = current->next->next;
                delete tmp;
            }
            else
            {
                current = current->next;
            }            
        }
    }        

    return head;
}

答案 3 :(得分:0)

deleted指针可指向任何位置。这是一种未定义的行为。删除后指针NULL是一个好习惯。它将明确确保您不会滥用指针而不是崩溃与空指针异常。我会改变你的代码: -

            if (curr!=NULL && prev->val == cur->val)
            {
                prev->next = cur ->next;
                delete cur;
                cur = NULL;
            }

编辑:我刚刚检查过删除后您正在使用

访问下一个
cut = cur->next;

在您的情况下,它可以在您使用固定数据执行代码时起作用,并且指针cur指向的内存未被覆盖。但是在相当复杂的程序中,很有可能cur成为其他东西而cur->next可以带你到宇宙中的任何地方(在大多数情况下,如果使用非平坦内存架构,则会出现分段错误)。但这是一个无意识的状态。因此,使它NULL肯定会给你错误。 最好退出异常,而不是做出意想不到的事情。

答案 4 :(得分:0)

代码肯定不行。代码坏了。删除cur = cur->next指向的对象后执行cur是未定义的行为。