当前位置:  开发笔记 > 编程语言 > 正文

是否在C中允许/安全地使用不同尺寸的结构?

如何解决《是否在C中允许/安全地使用不同尺寸的结构?》经验,为你挑选了1个好方法。

我有一些struct像这样的:

struct myStruct0 {
    void(*deallocMe)(void*); // points always to "myStruct0_dealloc"
    uint8_t* someStuff;
    void* someOtherStuff;
}
void myStruct0_dealloc(void* structPtr) {
    myStruct0* s = (myStruct0*)structPtr;
    free(s->someStuff);
    free(s->someOtherStuff);
    free(s);
}

struct myStruct1 {
    void(*deallocMe)(void*); // points always to "myStruct1_dealloc"
    uint8_t* someStuff;
    uint64_t largeArray[4096];
    void* someOtherStuff;
    char* someRealOtherStuff;
}
void myStruct1_dealloc(void* structPtr) {
    myStruct1* s = (myStruct1*)structPtr;
    free(s->someStuff);
    free(s->someOtherStuff);
    free(s->someRealOtherStuff);
    free(s);
}

无论structS和指针使用分配的malloc(当然不能是NULL).

以下代码是否安全?

struct genericForm {
    void(*deallocMe)(void*);
}

void deallocMyStructX(void* myStructX) {
    genericForm* x = (genericForm*)myStructX;
    x->deallocMe(myStructX);
}

我为什么要这样做?

我将有一个struct像上面的一些指针的数组,如果这将工作,我不必为每个struct/指针保存deallocator .这将真正简化我的代码.

编辑:结构可以完全不同.他们唯一共享的是它们包含表单的函数指针void(*)(void*)作为第一个元素.



1> Elias Van Oo..:

如果您只想访问结构的第一个成员,那么您应该没问题.第一个成员的偏移量保证为0,如果第一个成员与所有结构(即函数指针)兼容,那么你应该没问题.如果您要取消引用结构并访问其他成员,则可能会因填充而遇到问题.添加占位符成员可能会解决这个问题,但可能有点低效.

如果你没有太多的结构要担心,这可能是一个更简单的解决方案:

struct _data {
    int identifier;
    union {
        struct type_1 {} _t1;
        struct type_2 {} _t2;
        struct _generic {
            void (*dealloc_generic)(void *);//first member is dealloc function pointer
        } _gen;
    };
};
void dealloc_struct(struct _data * s)
{
    switch (s->identifier)
    {
        case 1:
            s->t1->delloc_t1_ptr(s->t1);
            return;
        //and so on
        default:
            //for generic-compatible structs
            s->_gen->delloc_generic(s->_gen);
    }
}

如果你的结构的第一个成员将始终是一个有效的函数指针,那么你甚至可以这样写:

void dealloc_struct(void *s)
{
    //cast s to function pointer, call it and pass the pointer as argument
    ((void (*)(void *))s)(s);
}

根据标准(C1x§6.7.2.1.13),这应该有效:

指向适当转换的结构对象的指针指向其初始成员[...],反之亦然.在结构对象中可能存在未命名的填充,但在其开头不是.

推荐阅读
echo7111436
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有