为何C++传递icmp指针无法修改原指针值?引用却可行?
为什么指针传递无法修改原始指针的指向?
先直接点出核心问题:你这里的指针传递本质还是值传递——函数接收的是原指针的副本,修改副本的指向不会影响原指针。而引用传递是直接绑定原变量,修改引用就是修改原变量本身。
一步步分析你的代码问题
1. unpack函数的参数是指针的副本
你的unpack函数定义是:
bool pinger::unpack(icmp *packet, int iphdrlen, int recv_len, char *buf)
这里的packet是一个局部指针变量,当你在echo里调用unpack(icmp_packet, ...)时,编译器会把icmp_packet的当前值(也就是buffer的起始地址)拷贝给packet。
在unpack里执行:
packet = (struct icmp *)(buf + iphdrlen);
这只是修改了局部变量packet的指向,让它指向buf+iphdrlen(也就是ICMP头的起始位置),但原指针icmp_packet的指向完全没变化——它还是指向buffer的起始地址(也就是IP头的位置)。
这就是为什么:
unpack里输出packet->icmp_type是69(正确的ICMP类型)echo里调用unpack前后输出icmp_packet->icmp_type都是0(因为它指向的是IP头或者被memset后的位置,不是ICMP头)
2. 为什么引用传递能生效?
如果把unpack的参数改成指针的引用:
bool pinger::unpack(icmp *&packet, int iphdrlen, int recv_len, char *buf)
这时候packet不再是副本,而是原指针icmp_packet的别名。当你在unpack里给packet赋值时,就是直接修改icmp_packet的指向,让它指向buf+iphdrlen。这样调用完unpack后,echo里的icmp_packet就指向正确的ICMP头位置,输出的类型自然就是正确的69了。
补充:修改指针指向的其他可选方式
除了用指针的引用,还有两种常见方法可以实现修改原指针的指向:
- 传递指针的指针(
icmp **packet),然后在函数里用*packet = (struct icmp *)(buf + iphdrlen);来修改原指针的指向 - 让
unpack函数返回新的指针地址,比如icmp* pinger::unpack(...) { ... return (struct icmp *)(buf + iphdrlen); },然后在echo里用icmp_packet = unpack(...);接收新地址
内容的提问来源于stack exchange,提问作者toliu
相关产品推荐
相关产品推荐

