问题
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