免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: aleenhu1983
打印 上一主题 下一主题

结构体指针为什么指向自己成员的时候出错了,请高手指点! [复制链接]

论坛徽章:
0
41 [报告]
发表于 2006-05-16 11:35 |只看该作者
为什么我的/usr/include/linux/if_ether.h里边就没有struct ether_arp
这个结构体呢

论坛徽章:
0
42 [报告]
发表于 2006-05-16 12:09 |只看该作者
我晕,看清楚一点,楼主!

struct        ether_arp {
        struct        arphdr ea_hdr;                /* fixed-size header */
        u_int8_t arp_sha[ETH_ALEN];        /* sender hardware address */
        u_int8_t arp_spa[4];                /* sender protocol address */
        u_int8_t arp_tha[ETH_ALEN];        /* target hardware address */
        u_int8_t arp_tpa[4];                /* target protocol address */
};
....
     printf("header:%d\n",a->eahdr);
      printf("dest ip = %d",a->tpa);
      printf("source ip =%d",a->spa);
      printf("dest mac =%d",a->tha);
      printf("source ip =%d",a->sha);

ea_hdr----eahdr??
arp_sha----sha??

论坛徽章:
0
43 [报告]
发表于 2006-05-16 12:19 |只看该作者
给你一个建议:
把你的所谓fixed-size header改成一个已知的数据类型(比如int,自定义的结构,总之不是某个你不知道的头文件中定义的),再试一下。如果没有这个错误就说明你引用的那个结构找不到,也就是头文件没有包含正确。

论坛徽章:
0
44 [报告]
发表于 2006-05-16 13:01 |只看该作者
有Ethernet和ARP协议。
if((*head==0x08&&(*(head+1)==0x06))  //判断协议,显示包数据
这个没错
但是你把head转换类型后给a,这个错了。0x0806表明是arp协议但是这两个字节它属于Ethernet帧,所以
a的具体位置应该在buffer+14,arp包头的开始地方。

[ 本帖最后由 hotjuly 于 2006-7-30 12:51 编辑 ]

论坛徽章:
0
45 [报告]
发表于 2006-05-16 13:26 |只看该作者
问题解决了.仔细监查了一下,确实是头文件引用路径不对.因为看一个法国人写的程序是那样的,自己也没太仔细看,只顾着找结构体的原定义去了!多谢各位的帮忙.其实是可以直接引用的.
#include <netinet/if_ether.h>
.......
void show_arp(void)
{
      printf("arp struct show:\n");
      printf("arp header:%c\n",arp->ea_hdr);
      printf("dest ip = %d",a->arp_tpa);
      printf("source ip =%d",a->arp_spa);
      printf("dest mac =%d",a->arp_tha);
      printf("source ip =%d",a->arp_sha);
}
OK啦!
其实有人说不能按%d的格式来printf是错误的,即使不指明a的成员数组的i值也是可以的,那就默认为是指向成员数组的首地址.
再次多谢大家的悉心指导

论坛徽章:
0
46 [报告]
发表于 2006-05-16 14:04 |只看该作者
原帖由 icestare 于 2006-5-16 10:43 发表
或者改成这样

  1. void show(struct ether_arp *a);
  2. int main(int argc, char *argv[])
  3. {
  4.      int i;
  5.      char buffer[65535] = {0};
  6.      unsigned char *head;
  7.      struct ether_arp *a;
  8.    ..........................................
  9.    //截包分析包头...
  10.     head=buffer+12;
  11.     a=(struct ether_arp *)head;
  12.     if((*head==0x0&&(*(head+1)==0x06))  //判断协议,显示包数据
  13.         show(a);
  14. }//endmain

  15. void show(struct ether_arp *a)
  16. {
  17.       printf("header:%d\n",a->eahdr);
  18.       printf("dest ip = %d",a->tpa);
  19.       printf("source ip =%d",a->spa);
  20.       printf("dest mac =%d",a->tha);
  21.       printf("source ip =%d",a->sha);
  22.       return;
  23. }
复制代码


这么多人说了这么多答案,其实就只有这一个是正确的。
原因就是buffer是main函数中的栈空间,不能在show()函数里得到,而作者的代码的show()函数是没有参数的,因此buffer中的内容在调用show()函数的时候并没有传给show()函数,也就是说
在show()函数中,printf("header:%d\n",a->eahdr); 这样的代码,其中的a指向的是未知的区域,a的类型也未知,因此出现了LZ的错误.

刚才对icestare 的答案做了实际测试,证明只有他的回答是正确的。
这确实是一个非常隐蔽的错误,一般人真很难察觉到.

在类似:
main()
{
...
char buffer[SIZE];
function();
...

}

void function (void)
{
  printf("%s" ,buffer)
}

这样的代码中,主函数中的缓冲区buffer是传不到fucntion里面的。 希望大家再对icestare的答案做一下测试也实验,看看到底对不对,我刚才在FreeBSD5.4自带的gcc中写了一个和LZ类似的代码测试了一下,结果证明icestare的回答是正确的。
改成以下代码后就可以:
main()
{
...
char buffer[SIZE];
function(buffer);
...

}

void function (char *buffer)
{
  printf("%s" ,buffer)
}

论坛徽章:
0
47 [报告]
发表于 2006-05-16 14:25 |只看该作者
明明是你的成员名字错误嘛,你和46楼引用的代码中的成员名字对对看

原帖由 aleenhu1983 于 2006-5-16 13:26 发表
问题解决了.仔细监查了一下,确实是头文件引用路径不对.因为看一个法国人写的程序是那样的,自己也没太仔细看,只顾着找结构体的原定义去了!多谢各位的帮忙.其实是可以直接引用的.
#include <netinet/if_ether.h ...

论坛徽章:
0
48 [报告]
发表于 2006-05-16 14:31 |只看该作者
你测测这个

#include <stdio.h>
char *s;
int main()
{
char buffer[1024];
sprintf(buffer,"OK!\n");
s=buffer;
function();

}

int function ()
{
  printf("%s" ,s);
}


原帖由 gucuiwen 于 2006-5-16 14:04 发表


这么多人说了这么多答案,其实就只有这一个是正确的。
原因就是buffer是main函数中的栈空间,不能在show()函数里得到,而作者的代码的show()函数是没有参数的,因此buffer中的内容在调用show()函数的时候并没有 ...

论坛徽章:
0
49 [报告]
发表于 2006-05-16 16:38 |只看该作者
"第二场雪"真是幽默

论坛徽章:
0
50 [报告]
发表于 2006-05-16 16:58 |只看该作者
原帖由 shaver 于 2006-5-16 14:31 发表
你测测这个

#include <stdio.h>
char *s;
int main()
{
char buffer[1024];
sprintf(buffer,"OK!\n");
s=buffer;
function();

}

int function ()
{
  printf("%s" , ...

这个可以执行啊.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP