@
ColorfulBoar 很久没写 cpp ,我调试了下,请看注释的部分吧:
#include <stdio.h>
struct list_node;
using list_head = list_node *;
struct list_node
{
list_head next;
int value;
};
void remove(list_head &head, list_head target)
{
// 这里确实是二级指针,其实内存已经乱掉了;
// 但因为 list_node 的第一个字段是 next 指针,而你的 p 的值是 head 的值,也就是说,p作为 list_node 的第一个字段的值刚好跟 head 是内存是同一段内存
auto p = list_head(&head);
// 所以这里的 while 循环的第一次判断 (p-> != target) 实际上是判断 head != target ,所以整个循环下来,也能得到正确的结果
// 但是这依赖于 list_node 的字段的内存布局,list_node 的 next 字段必须是结构体第一个字段才能正确运行
// 否则,把 value 放在 next 前面,或者在前后中间再多加点字段,野指针可能就 coredump 了,或者运气好由于出入栈之类的刚好指向了哪个 ok 的地址没 coredump 但是也没有删除成功,我已经试过了,不信你改下代码试试
// 当然你也可以把 head p 以及他们作为指针只想的 list_node 各个字段的值都打印出来,然后你就发现了,p->next == head ,这只是内存布局巧合导致你运气好而已
// 单纯讨论 cpp ,正确的写法应该是 auto p = head;
int cnt = 0;
while (p->next != target)
{
p = p->next;
cnt++;
}
p->next = target->next;
printf("cnt: %d\n", cnt);
}
void travel(list_head head)
{
printf("----------------------\n");
auto p = head;
while (p)
{
printf("value: %d, %p, %p\n", p->value, p, p->next);
p = p->next;
}
printf("----------------------\n");
}
int main()
{
list_node node1, node2, node3;
node1.value = 1;
node2.value = 2;
node3.value = 3;
node1.next = &node2;
node2.next = &node3;
node3.next = nullptr;
list_head head = &node1;
list_head target = &node2;
travel(head);
remove(head, target);
travel(head);
}
@
cnbatch #98 所以按你说的,我 #46 最初就没说错对吧?我是被他第一次说我不够资格还以为是什么 11 之后的高级东西我确实不懂呢,也看下我上面调试的吧,如果我说的没问题,那你们之前就没人仔细看下他这个代码啊?。。。:joy: