免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10715 | 回复: 17
打印 上一主题 下一主题

使用结构体内部成员的指针是否属于c/c++编程的忌讳? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-10-18 15:06 |只看该作者 |倒序浏览
这应该不是简单的“字节对齐”的问题。
假设定义结构体

  1. struct a{
  2.        char buff[MAX_BUFF_SIZE];//有可能是4字节的整数倍也有可能不是
  3.       int    nV;
  4.      void  *p;
  5.      .... //总之是有各种成员
  6. }
  7. struct b
  8. {
  9.    ..//也有多种类型的成员
  10. }
  11. struct c //包含以上两个结构体变量的结构体
  12. {
  13.       int    nV1;
  14.       void *p
  15.       struct a  AA;
  16.       struct B BB
  17. }

  18. 那么定义一个 struct c  的结构体变量
  19. struct c  cc;
  20. struct a *pa= & cc.AA;
  21. struct b *pb= & cc.BB;
复制代码

我不论pa或pb在结构体里相对结构体首指针的偏移量为多少,不管它内存如何字节对齐,只想知道指针pa或pb是否真实的指向cc的成员变量AA或BB.

理论上,照说&操作符是取到了成员变量的地址并通过=操作符赋值给指针了,然后就可以通过指针操作该成员变量。但发现在“某些情况”下会出错,取到的地址和结构体成员真正的内存地址不一致(即使结构体成员的内存情况在调试器窗口看到是正确的)。

非常奇怪,不知道是编译器问题还是代码问题,有同事说这是c语言编程的禁忌之一,我以前倒没听说过。各位看法如何?
看图,这是在用vc作为调试器时发现的问题,
recConn *p= &pConnSet->;rClient
但p和 &pConnset->;rClient的地址值却相差10多个字节。

论坛徽章:
0
2 [报告]
发表于 2004-10-18 15:44 |只看该作者

使用结构体内部成员的指针是否属于c/c++编程的忌讳?

是不是Windows才这样啊?Unix没遇到过。

论坛徽章:
0
3 [报告]
发表于 2004-10-18 15:54 |只看该作者

使用结构体内部成员的指针是否属于c/c++编程的忌讳?

[quote]原帖由 "FH"]是不是Windows才这样啊?Unix没遇到过。[/quote 发表:

我也郁闷呀,前两年都是写unix上的程序,偶尔写点windows上的代码,都没有遇到过类似的情况。
先是怀疑结构体对齐情况有问题,于是定义#pragma pack(1),或在工程C/C++->;Code Generation里设置对齐为1,没有用。

然后怀疑是cpp和c混编问题(MFC工程,出问题的代码是在.c文件,曾经跑的比较好的代码),将代码所在的c文件改成cpp重新编译(c++严格类型检查,增加了不少代码修改量,苦)。还是没有用。

无奈,修改rClient所在结构体pConnSet的定义,使其所有内部成员都严格按4字节对齐,内部成员的整形,枚举,字符串变量分别连续放置。重新编译好象可以了...

但就是狂不明白,狂不甘心!
除了怀疑编译器问题之外,不知道还有什么原因

论坛徽章:
0
4 [报告]
发表于 2004-10-18 15:57 |只看该作者

使用结构体内部成员的指针是否属于c/c++编程的忌讳?

偶用VC试了一把,没有楼主说的那样啊,这个东西怎么会是c的什么什么的,说这样的话的人真土,p的值就是&之后取的,如果真有问题,有问题的也是VC编译器或者调试器,跟c/c++语言有什么关系,最多也是编译器实现的问题,人家也是软件....不知道楼主能不能把你出问题的代码给偶一份看看,反正偶这里是没这个问题的。附上偶的调试程序,楼主验证下看看
struct a
{
        char buff[10];
        int i_a;
        int i_b;
};

struct b
{
        int i_c;
        int i_d;
};

struct c
{
        int i_e;
        struct a r_a;
        struct b r_b;
};

{
....
        struct c r_c;
        r_c.i_e = 0;
        memset(r_c.r_a.buff, 0x00, sizeof(r_c.r_a.buff));
        r_c.r_a.i_a = 1;
        r_c.r_a.i_b = 2;
        r_c.r_b.i_c = 1;
        r_c.r_b.i_d = 2;

        struct a *pa;
        struct b *pb;

        pa = &r_c.r_a;
        pb = &r_c.r_b;

        pa->;i_a = 0;
        pb->;i_c = 0;
....
}

论坛徽章:
0
5 [报告]
发表于 2004-10-18 16:19 |只看该作者

使用结构体内部成员的指针是否属于c/c++编程的忌讳?

原帖由 "virmin" 发表:
nt i_a;
        int i_b;
};

struct b
{
        int i_c;
        int i_d;
};

struct c
{
        int i_e;
        struct a r_a;
        struct b r_b;
};

{
....
        struct c r_c;
        r_c.i_e = 0;
        memset(r_c.r_a.buff, 0x00, siz..........


我也是认为是编译器问题,可惜手头没有其他操作系统,也懒得下其他编译器调试一吧...我也写过写其他代码测试,结果和你的类似,只有那个比较大的结构体出问题。所以我觉得也许属于个案或者很偏锋的问题,开贴请教一下看有没有遇到过的。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2004-10-18 16:55 |只看该作者

使用结构体内部成员的指针是否属于c/c++编程的忌讳?

应该不会的。
尽量不要怀疑编译器,先从自身找原因。

论坛徽章:
0
7 [报告]
发表于 2004-10-18 17:01 |只看该作者

使用结构体内部成员的指针是否属于c/c++编程的忌讳?

原帖由 "flw" 发表:
应该不会的。
尽量不要怀疑编译器,先从自身找原因。


找了一夜,精疲力尽,终于在发疯前凑合能跑起来了(修改一些成员的字节对齐情况,比如char a[7]修改成a[8], 所有int依次定义,所有enum依次定义,所有void *依次定义...)....如果不是象我那个同事说的那么恐怖(什么忌讳之类的),我就这样先用着了先。

论坛徽章:
0
8 [报告]
发表于 2004-10-18 17:09 |只看该作者

使用结构体内部成员的指针是否属于c/c++编程的忌讳?

呵呵,稀罕的问题。你VC的pack都打好了吗?
你可以写封信去问微软。。。

论坛徽章:
0
9 [报告]
发表于 2004-10-18 17:10 |只看该作者

使用结构体内部成员的指针是否属于c/c++编程的忌讳?

也许是哪里把指针的地址不小心改掉了

论坛徽章:
0
10 [报告]
发表于 2004-10-18 17:25 |只看该作者

使用结构体内部成员的指针是否属于c/c++编程的忌讳?

[quote]原帖由 "Moonwellatg4"]也许是哪里把指针的地址不小心改掉了[/quote 发表:


无论怎么对结构体本身memset,memcp,但&操作符所获取的内存变量地址应该不应该有什么不同吧,除非什么操作把调用堆栈里的变量地址描述段整个改了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP