我有这段代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
struct node* next;
int data;
}NODE;
NODE* makeNode (int x){
NODE* new;
new = (NODE*)malloc(sizeof(NODE));
new -> data = x;
new -> next= NULL;
return new;
}
typedef NODE* linkedlist;
void insertnode (NODE** node, int x){
if(!(*node))
*node=makeNode(x);
else
insertnode(&((*node)->next), x);
}
void deletenode(NODE** node){
(*node)=NULL;
free (*node);
}
int main()
{
NODE* node;
linkedlist mylist;
mylist=NULL;
insertnode(&mylist, 3); //insert a node
insertnode(&mylist, 4);
node = mylist->next; //
deletenode(&(mylist->next));
printf("\n%d\n",node->data); // prints 4
return 0;
}
我正在研究二元搜索树,当我到达删除部分时,我开始怀疑指针如何在记忆中起作用,我的世界崩溃了。
我会使用这个链表代码而不是BST代码,因为我更容易解释我的怀疑。
好吧,如果我这样做node=NULL;
mylist仍然存在,因为node是指向mylist的指针的副本,但是当我这样做时:
free(node->next);
node->next=NULL;
mylist-&gt; next将不再存在,因为node->next
是下一个节点的原始指针。
所以在代码中我在mylist->next
node
指针
node = mylist->next;
我认为这是发生的事情:
MYLIST --------------&GT; [|数据|下|] - GT; [|数据|下|] LT; ----------- -------节点;
然后我删除原始节点。但是,当我打印node->date
时,程序会打印出4。
我理解指针是包含内存位置的变量。但我不明白为什么node->data;
仍然存在,如果我释放节点并设置它NULL;
只影响指针而不是内存?
当我释放并且NULL一个指针时,内存会阻塞指针保存的内容吗?
我的问题在于指向结构的指针,以及它们如何与它们指定的内存一起工作。
我希望我能让我理解,我的英语不太好。
答案 0 :(得分:2)
释放后访问内存会调用未定义的行为。 一些可能的结果是:
但是这个列表并不全面,其他一些也可能发生。
外卖是,永远不要从已释放的内存位置访问数据。
答案 1 :(得分:1)
指针指向内存位置。
在free()
之后,您将已分配的内存返还给操作系统。
访问此内存是UB(未定义的行为)
所以你可能会看到预期的结果,但由于你有UB,所以不能保证这一点。
在你的情况下,假设你释放指针mylist-&gt;接下来指向的内存。
free(mylist->next)
mylist->next = NULL;
现在指针mylist->next
保存的内存将返回给操作系统。由于该内存可供操作系统使用,因此可以对其执行任何操作。在你的情况下,它现在写任何东西到这个位置并保留free()
之前的内容,所以你回来4
但是如果这个记忆用于分配到另一个目的那么你可能没有得到什么你期待的。
所以基本上访问被释放的内存会导致UB