C++实现链表时同一指针在主函数与被调函数中地址不同的咨询
C++链表传参地址不一致、遍历异常问题解答
为什么main中head_1和iter形参head的地址不一样
这是C++值传递机制的正常表现,不属于错误:
- 函数调用时实参传入形参的本质是拷贝赋值:系统会在
iter函数的独立栈空间内,给形参head单独分配一块指针大小的内存,把head_1存储的内容(也就是链表头节点的内存地址)复制到这块新内存中。 - 你打印的
&head_1是main函数栈帧里head_1这个指针变量自身的内存地址;&head是iter函数栈帧里形参head这个指针变量自身的内存地址。两个是完全独立的变量,地址本来就不可能相同。 - 如果要验证传参是否正确,应该打印指针变量存储的指向地址,也就是直接输出
cout << head_1和cout << head,二者结果会完全一致,说明两个指针都指向同一个链表头节点。
链表打印异常的真正原因
你现在能输出0 2 4 6 8属于未定义行为下的巧合,代码里有两个明确的逻辑错误:
- 遍历顺序写反了
iter函数里你先移动指针、再打印数据:
while(cur!=NULL){ cur = cur->next; cout<<cur->data<<' '; }
当cur走到最后一个有效节点时,进入循环后第一步就会把cur赋值为NULL(最后一个节点的next固定为NULL),接下来访问cur->data就是空指针访问,会触发内存错误,轻则打印乱码,重则程序直接崩溃。
2. 初始头节点是未初始化的哑节点create函数里你第一次malloc得到的head节点没有给data赋值,是个存储了垃圾值的无效节点,你当前的遍历逻辑刚好跳过了这个节点,才碰巧打出了后面存入的有效数据,但空指针访问的隐患始终存在。
修正参考
把遍历逻辑调整为先打印、后移动指针,同时跳过未初始化的哑节点即可:
void iter(link_node* head){ link_node* cur = head->next; // 从第一个存了有效数据的节点开始遍历 cout<<"The value of head pointer in function: "<<head<<endl; while(cur!=NULL){ cout<<cur->data<<' '; cur = cur->next; // 打印完成后再移动指针 } }
额外注意:C++开发中申请内存建议用new代替malloc,malloc不会调用类的构造函数,很容易引发未定义问题。
内容的提问来源于stack exchange,提问作者JPPPPP
相关产品推荐
相关产品推荐

