c define arrays in struct with different sizes

前端 未结 3 1176
南方客
南方客 2021-01-21 09:08

I need to define a struct for two types of objects. Both have exactly the same data structure and perform same tasks (member methods).

The ONLY difference is that the a

相关标签:
3条回答
  • Even with a union, the struct will be as big as the largest of the two arrays.

    Do one of these:

    1. Ignore the overhead of the biggest array size. (Use one array or a union)
    2. Create a separate struct for each type.
    3. Dynamically allocate the array with malloc.
    0 讨论(0)
  • 2021-01-21 09:56

    I would make matr a flexible array at the end of your struct. Then, I would stick the arr array into the last row of matr.

    typedef struct {
        int size;
        int var1, var2;
        int matr[];
    } s;
    
    static inline int size_ok_s (int size) {
        switch (size) {
        case SIZE_A:
        case SIZE_B:
            return 1;
        default:
            break;
        }
        return 0;
    }
    
    s * create_s (int size) {
        s *x = 0;
        if (size_ok_s(size)) {
            x = malloc(sizeof(*x) + sizeof(int[size+1]));
            if (x) x->size = size;
        }
        return x;
    }
    

    To achieve a uniform interface, you can use a macro:

    #define s_matr(x) ((int (*)[(x)->size])(size_ok_s((x)->size) ? (x)->matr : 0))
    #define s_arr(x)  (s_matr(x)[(x)->size])
    

    So, to access the ith row and jth column of s *foo's matr, and its kth element of arr:

    s *foo = create_s(SIZE_A);
    /* ... */
        s_matr(foo)[i][j] = 0;
        s_arr(foo)[k] = 0;
    

    Flexible array members are a new feature of C.99 described in §6.7.2.1 ¶16. Prior to C.99, C programmers often used what was known as the struct hack:

    typedef struct {
        int size;
        int var1, var2;
        int matr[1];
    } s;
    
    s * create_s (int size) {
        s *x = 0;
        if (size_ok_s(size)) {
            x = malloc(sizeof(*x) + sizeof(int[size]));
            if (x) x->size = size;
        }
        return x;
    }
    

    This is a hack since in C.89-90, indexing the matr array with a value greater than 0 is technically accessing an object beyond its boundary. However, it was a common practice, and widely portable. C.99 formally sanctioned the mechanism with the flexible array member, although it requires the syntax of not specifying a size in the array declaration.

    0 讨论(0)
  • 2021-01-21 10:02

    Have the arrays be pointers and allocate to them (the appropriate size) as needed. Only downsize is access to the 2D array will be a little clumsy.

    0 讨论(0)
提交回复
热议问题