Setting the size of an array inside a struct with a value of another value within the same struct, in C

坚强是说给别人听的谎言 提交于 2020-01-17 02:47:40

问题


    struct {
        uint16 msg_length;
        uint8 msg_type;
        ProtocolVersion version;
        uint16 cipher_spec_length;
        uint16 session_id_length;
        uint16 challenge_length;
        V2CipherSpec cipher_specs[V2ClientHello.cipher_spec_length];
        opaque session_id[V2ClientHello.session_id_length];
        opaque challenge[V2ClientHello.challenge_length;
    } V2ClientHello;

Is it possible to do something similar to the above (http://tools.ietf.org/html/rfc5246)? If so how do I go about coding this inside C?

To be more specific this line in the struct:

V2CipherSpec cipher_specs[V2ClientHello.cipher_spec_length];


Uses:

V2ClientHello.cipher_spec_length


Which is defined in the same struct, to set the length of the array.


回答1:


C does not support dynamic-sized arrays. To achieve your goal, you can use a pointer of type V2CipherSpec as structure variable and allocate memory at a later stage using the V2ClientHello.cipher_spec_length value.




回答2:


Absolutely not. C does not have dynamic-size arrays. Instead, we can rely on tricks like this:

struct {
    uint16 msg_length;
    uint8 msg_type;
    ProtocolVersion version;
    uint16 cipher_spec_length;
    uint16 session_id_length;
    uint16 challenge_length;
    char extra[0]; // or 1 if your compiler hates this
} V2ClientHello;

Then, do not create instances of this struct directly, but rather via malloc():

struct V2ClientHello* hello = malloc(sizeof(V2ClientHello) + 
    len1*sizeof(V2CipherSpec) + len2 + len3);

Now you have a dynamically-allocated structure of the size you need. You can make accessor functions to get the "extra" fields:

V2CipherSpec* get_spec(V2ClientHello* hello, int idx) {
    assert(idx < hello->cipher_spec_length);
    return ((V2CipherSpec*)&hello->extra)[idx];
}

And of course you can wrap up the malloc() call inside a create routine which takes the sizes of all three dynamic parts and does everything in one place for robustness.




回答3:


The shown code from the RFC is pseudo code, you can not implement it as shown.

You need to allocate these arrays manually depending on V2ClientHello.cipher_spec_length and the other length specification fields, once their values are known.




回答4:


Value of "V2ClientHello.cipher_spec_length" is not available at compile time. You can not specify the size of an array at run time, instead use:

V2CipherSpec *cipher_specs;

in struct and use malloc or calloc to allocate a block of memory at run time.

V2ClientHello.cipher_specs = (V2CipherSpec *)malloc(V2ClientHello.cipher_spec_length);



来源:https://stackoverflow.com/questions/25763343/setting-the-size-of-an-array-inside-a-struct-with-a-value-of-another-value-withi

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!