关于结构的指针及其工作原理

时间:2023-01-12 22:29:18

i have this code:

我有这个代码:

 #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;
}

I was studyng binary search trees and when i arrive to the deletion part i started to doubt about how pointers works in memory and my world got collapsed.

我正在研究二元搜索树,当我到达删除部分时,我开始怀疑指针如何在内存中工作,我的世界崩溃了。

I will use this linked list code instead the BST code because is more easy to me for explain my doubts.

我将使用这个链表代码而不是BST代码,因为我更容易解释我的怀疑。

Well, if i do this node=NULL; mylist will still exist because node is a copy of the pointer to mylist, but when i do this:

好吧,如果我这样做node = NULL; mylist仍然存在,因为node是指向mylist的指针的副本,但是当我这样做时:

free(node->next);
node->next=NULL; 

mylist->next will no longer exist because node->next is the original pointer of that next node.

mylist-> next将不再存在,因为node-> next是该下一个节点的原始指针。

So in the code i did a copy of mylist->next pointer in node

所以在代码中我在节点中做了一个mylist-> next指针的副本

node = mylist->next;

i assume this is what happen:

我认为这是发生的事情:

mylist-------------->[|data|next|]->[|data|next|]<------------------node;

Then i delete the original node. But when i print node->date for my surprise the program prints 4.

然后我删除原始节点。但是当我打印节点 - >日期让我惊讶的是程序打印4。

I understand thats the pointers are variables that hold a memory location. But i can't get why node->data; still exist if i'd set free the node and set it NULL; just affected the pointer and not the memory?

我知道指针是包含内存位置的变量。但我无法得到为什么node-> data;如果我释放节点并将其设置为NULL,则仍然存在;只是影响了指针而不是内存?

when i free and NULL a pointer what happens with the memory blocks what that pointer holds?

当我释放和NULL指针时,内存会发生什么阻塞指针所拥有的内容?

My problems is with the pointers to structs, and how they work with the memory allocated pointed by them.

我的问题是指向结构的指针,以及它们如何使用它们指定的内存分配。

I hope i make me understand, my english is't so good.

我希望我能让我理解,我的英语不是那么好。

2 个解决方案

#1


1  

Pointer points to a memory location.

指针指向内存位置。

After free() you are giving back the allocated memory back to OS.

在free()之后,您将分配的内存返回给OS。

Accessing this memory is UB(Undefined behavior)

访问此内存是UB(未定义的行为)

So you might see expected result but since you have UB this is not guaranteed at all time.

因此,您可能会看到预期的结果,但由于您有UB,因此无法始终保证。

In you case let's say you free the memory the pointer mylist->next is pointing to.

在你的情况下,让我们说你释放指针mylist-> next指向的内存。

free(mylist->next)
mylist->next = NULL;

Now the memory held by the pointer mylist->next is returned back to OS. Since this memory is available to the OS it can do anything with it. In your case it now writing anytihng to this location and retaining what is there before the free() so you are getting back 4 but if this memory was used to allocate to someother purpose then you might have not got what you expected.

现在指针mylist-> next持有的内存返回给OS。由于该内存可供操作系统使用,因此它可以对其执行任何操作。在你的情况下,它现在写anytihng到这个位置并保留free()之前的内容,所以你回来4但是如果这个内存用于分配到另一个目的那么你可能没有得到你所期望的。

So basically accessing the memory which is freed leads to UB

所以基本*问释放的内存会导致UB

#2


2  

Accessing memory after freeing invokes undefined behavior. Some possible outcomes are:

释放后访问内存会调用未定义的行为。一些可能的结果是:

  • You may get the data that was previously lodged at that address.
  • 您可能会获得之前寄存在该地址的数据。

  • You may get zero or some other value
  • 您可能会得到零或其他值

  • Program may crash
  • 程序可能崩溃

But this list is not comprehensive, some else may also happen.

但是这个列表并不全面,其他一些也可能发生。

Takeaway is, never access a data from memory location that is freed.

要点是,永远不要从被释放的内存位置访问数据。

#1


1  

Pointer points to a memory location.

指针指向内存位置。

After free() you are giving back the allocated memory back to OS.

在free()之后,您将分配的内存返回给OS。

Accessing this memory is UB(Undefined behavior)

访问此内存是UB(未定义的行为)

So you might see expected result but since you have UB this is not guaranteed at all time.

因此,您可能会看到预期的结果,但由于您有UB,因此无法始终保证。

In you case let's say you free the memory the pointer mylist->next is pointing to.

在你的情况下,让我们说你释放指针mylist-> next指向的内存。

free(mylist->next)
mylist->next = NULL;

Now the memory held by the pointer mylist->next is returned back to OS. Since this memory is available to the OS it can do anything with it. In your case it now writing anytihng to this location and retaining what is there before the free() so you are getting back 4 but if this memory was used to allocate to someother purpose then you might have not got what you expected.

现在指针mylist-> next持有的内存返回给OS。由于该内存可供操作系统使用,因此它可以对其执行任何操作。在你的情况下,它现在写anytihng到这个位置并保留free()之前的内容,所以你回来4但是如果这个内存用于分配到另一个目的那么你可能没有得到你所期望的。

So basically accessing the memory which is freed leads to UB

所以基本*问释放的内存会导致UB

#2


2  

Accessing memory after freeing invokes undefined behavior. Some possible outcomes are:

释放后访问内存会调用未定义的行为。一些可能的结果是:

  • You may get the data that was previously lodged at that address.
  • 您可能会获得之前寄存在该地址的数据。

  • You may get zero or some other value
  • 您可能会得到零或其他值

  • Program may crash
  • 程序可能崩溃

But this list is not comprehensive, some else may also happen.

但是这个列表并不全面,其他一些也可能发生。

Takeaway is, never access a data from memory location that is freed.

要点是,永远不要从被释放的内存位置访问数据。