垂悬指针问题

来源:互联网 发布:淘宝花呗客服在哪里找 编辑:程序博客网 时间:2024/04/29 11:36

问题

垂悬指针问题,这个问题的定义我是知道的。通常是说当指向某块内存的指针被释放之后,需要及时置空。否则,如果不置空,当下次不小心访问到时,会导致错误。当然,这个问题说起来很简单。觉得也没什么太大的问题,但是指针这一块确实得非常小心,从下面我范的这个问题说起。

下面这段代码是我刷leetcode的时候的一段代码,主要删除链表中重复的元素。当然下面的代码是正确的。

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* removeElements(ListNode* head, int val) {        if(!head) return NULL;        ListNode* ret = head;        ListNode* pre = NULL;        while( head ){            if(head->val == val)            {                ListNode* cur = head;                if(pre)                     pre->next = head->next;                    head = head->next;                }                else                {                    head = head->next;                    ret = head; // 这里没有,一直RE                }                delete cur;            }            else            {                pre = head;                head = head->next;            }        }        return ret;    }};

但是,我第一次写的时候,在注释处的代码是没有的,也就是说我忘了更新ret的值。代码就一直RE。
那么我们仔细分析一下这个问题,对于ret的更新,是在头结点被删除的时候才会。那么如果不更新会导致什么结果呢?对于头结点来说,ret和head都指向他,程序在执行循环的时候,发现头结点的值和val一样,所以考虑删除这个节点,那么此时 delete head.会释放这段空间,由于head又指向了下一个节点,所以并不会出现垂悬指针问题。但是本题的问题出现的非常隐蔽,当多个指针指向一块内存时,此时用head释放了该处内存,但是ret任然指向这块内存。所以,最后返回的时候,对ret的访问会导致RE。因为ret在之前应该被置位垂悬指针,否则访问后就会出现错误。本题就是栽在了这个上面。

所以,当多个指针指向同一块内存时,务必保证当这块内存释放时,一定要把指向这块内存的所有指针都置空

0 0
原创粉丝点击