C 语言中结构体相互嵌套有什么优点吗 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Persona0x4343
V2EX    C

C 语言中结构体相互嵌套有什么优点吗

  •  
  •   Persona0x4343 2019 年 1 月 10 日 5166 次点击
    这是一个创建于 2575 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近看 wpa_supplicant 的代码,发现有许多的结构体都相互嵌套

    什么情况下我们会选择这种相互嵌套的结构?

    例如下面的 wpa_supplicant 和 wpa_global

    exp:

    struct wpa_supplicant { struct wpa_global *global; struct wpa_radio *radio; /* shared radio context */ structdl_list radio_list; /* list head: struct wpa_radio::ifaces */ struct wpa_supplicant *parent; struct wpa_supplicant *p2pdev; struct wpa_supplicant *next; struct l2_packet_data *l2; struct l2_packet_data *l2_br; unsigned char own_addr[ETH_ALEN]; unsigned char perm_addr[ETH_ALEN]; char ifname[100]; ... 
    struct wpa_global { struct wpa_supplicant *ifaces; struct wpa_params params; struct ctrl_iface_global_priv *ctrl_iface; struct wpas_dbus_priv *dbus; struct wpas_binder_priv *binder; void **drv_priv; size_t drv_count; struct os_time suspend_time; struct p2p_data *p2p; struct wpa_supplicant *p2p_init_wpa_s; struct wpa_supplicant *p2p_group_formation; struct wpa_supplicant *p2p_invite_group; ... 
    14 条回复    2019-01-11 08:13:12 +08:00
    wizardoz
        1
    wizardoz  
       2019 年 1 月 10 日
    这个不叫嵌套好吧,顶多算是一种关联。
    wizardoz
        2
    wizardoz  
       2019 年 1 月 10 日   2
    就好比双向链表,a 的 next 指向 b,b 的 prev 指向 a。你不能说它是相互嵌套啊
    jagger2048
        3
    jagger2048  
       2019 年 1 月 10 日   2
    相互嵌套 谈不上,用个结构体封装其他结构体指针,可以比较方便地管理资源,如果是 C++可以用类的某些特性(派生继承多态)来封装
    aijam
        4
    aijam  
       2019 年 1 月 10 日
    爹认识儿子,儿子也要认识爹。
    zn
        5
    zn  
       2019 年 1 月 10 日
    这个叫互相引用,不叫互相嵌套。
    GeruzoniAnsasu
        6
    GeruzoniAnsasu  
       2019 年 1 月 10 日   1
    这是个每个节点都带有指向根节点指针的树结构
    wutiantong
        7
    wutiantong  
       2019 年 1 月 10 日
    99%的 C 语言项目都能看到这种“相互嵌套”,题主一定是没用 C 语言做过工程实践。
    dazhangpan
        8
    dazhangpan  
       2019 年 1 月 10 日
    有点就是互相都知道地址,去谁家串个门都方便
    liuxey
        9
    liuxey  
       2019 年 1 月 10 日
    互相引用这种事情别说 C,Java 里也很常见嘛,还记得一对多和多对多吗
    reus
        10
    reus  
       2019 年 1 月 10 日
    那是指针,存的是指针,没有嵌套

    真的嵌套的话,是编译不过的,因为结构体大小是无限大,没法编译
    flyingghost
        11
    flyingghost  
       2019 年 1 月 10 日
    相互嵌套。。。吓我一大跳,申请一个实例直接就爆内存了啊喂!

    只是互相关联,互相存一个指针而已。莫慌,莫慌。
    FrankHB
        12
    FrankHB  
       2019 年 1 月 10 日   1
    看起来是作者水平比较屎,因为无知或盲信 Linux Kernel Coding Style 5)之类的反智胡扯,不知道用显式类型体现更明确的目的(考虑到下面的 magic,前者跑不掉)。换 C 艹可能就被打死了。
    真正互相引用的像链表的 prev/next 的情况理应是非常少的,并且基本可以且往往应该排除出业务代码。
    然后看了下代码(主要是 wpa_supplicant_deinit_iface ),果然是属于混用所有权和链表访问的需要被打死的情况。在我这边 review 避免被打死的标准套路起手( C 艹版本)是 wpa_supplicant *ifaces 改成 pmr::list<wpa_supplicant> ifaces,struct wpa_global *global 改成 observer_ptr<wpa_global>。C 嘛要考虑的细节麻烦多了(……比如避免_t 踩到 POSIX reserve name ),懒得示范了。
    FrankHB
        13
    FrankHB  
       2019 年 1 月 10 日
    贴漏了,observer_ptr<wpa_global>后补 global。另外看起来是内部用的,不管 ABI compat 直接改 pmr::forward_list 好了,更接近原逻辑。

    @jagger2048 知道是 C 代码就别拿 C 艹的习惯说大话了,看看实际代码就知道不符合你这里说的任何一种情况(尽管看的确实是“资源管理”有点关系的代码)。
    Persona0x4343
        14
    Persona0x4343  
    OP
       2019 年 1 月 11 日
    @GeruzoniAnsasu 谢谢,我数据结构就了解到链表那里,会去补一下相关知识
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3260 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 11:42 PVG 19:42 LAX 03:42 JFK 06:42
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86