指针(技巧):内存参考

CHA*_*APa -4 c c++ pointers memory-management

关于C指针的技巧问题.请阅读下面的代码段并尝试解释列表值更改的原因(此问题基于代码):

tail具有列表的内存地址.

如何在下面更改可能的列表

typedef struct _node {
   struct _node *next;
   int value;
}Node;


 int main(){
   Node *list, *node, *tail;
   int i = 100;

   list = NULL;
   printf("\nFirst . LIST value = %d", list);

  tail =(Node *) &list;
  node = malloc (sizeof (Node));
  node->next = NULL;
  node->value = i;

  //tail in this point contains the memory address of list
  tail->next = node;
  printf("\nFinally. LIST value = %d", list);
  printf("\nLIST->value = %d", (list->value));

return 0;
Run Code Online (Sandbox Code Playgroud)

}

----输出

首先 列表值= 0

为什么这个值??? 我不期待这个......

最后.列表值= 16909060

列表 - >值= 100

Sco*_*les 10

让我们来看看你的程序中的内存会发生什么.您从3个局部变量开始,所有变量都是类型Node*.目前他们都指向垃圾,因为他们已经宣布但没有初始化.

内存的ascii art图可能是(布局依赖于实现)

      list   node   tail
  --------------------------
... | 0xFE | 0x34 | 0xA3 | ...
  --------------------------
Run Code Online (Sandbox Code Playgroud)

然后将列表设置为NULL,并将tail节点的地址(丢弃其类型,一个坏主意)设置为给您

      list   node   tail
  --------------------------
... | NULL | 0xFE | &list | ...
  --------------------------
        ^             |
        +-------------+
Run Code Online (Sandbox Code Playgroud)

然后Node,您将一个新的设置列表malloc 到其地址.

      list    node   tail          next  value
  ---------------------------  ------------------
... | NULL | &next | &list | ... | NULL | 100 | ...
  ---------------------------  ------------------
        ^      |       |             ^
        |      +---------------------+
        +--------------+
Run Code Online (Sandbox Code Playgroud)

接下来尝试设置tail->next为节点.您已经说过,当您进行类型转换时,您就知道tailNode这一点,因此编译器会相信您.该Node尾点在开始list的地址,像这样

     tail                                list
     next    value                       next   value
  ----------------------------------  ------------------
... | NULL | &list->next | &list | ... | NULL | 100 | ...
  ----------------------------------  ------------------
Run Code Online (Sandbox Code Playgroud)

然后,您可以tail->nextnode,作listnode指向list结构.

      list    node   tail          next  value
   ---------------------------  ------------------
... | &next | &next | &list | ... | NULL | 100 | ...
   ---------------------------  ------------------
       | ^     |       |             ^
       | |     +---------------------|
       | +-------------+             |
       +-----------------------------+
Run Code Online (Sandbox Code Playgroud)

您已打印list为有符号整数("%d").这是个坏主意 - 如果你使用的是64位机器并且在printf语句中有其他参数,那么它们可能会被破坏,请使用指针格式("%p").list->value是一样的node->value,所以它仍然会是100.

如果你考虑它们在机器中的实际表现方式,指针变得更容易 - 作为一个包含所有数据的大数组的索引(模数指针大小,虚拟内存等).

下次使用起来可能更容易list = node.