Physics and Astronomy |
Back to top
On this page
Contents Appendix: flexible arrays in structuresThe occasional appendices and optional examples in this module are for advanced material that you will not need for this module. They are intended for enthusiastic students who are interested in going further in programming for its own sake. Suppose we have a structure with an array as its last member: typedef struct foostr { int n; float vals[2]; } Foostr; Clearly this is an array of length two and the structure is 12 bytes long (assuming 4-byte floats and ints). But suppose we cheat and allocate more that that: Foostr *q; q = malloc(sizeof *q + 4 * sizeof q->vals[0]); We've allocated enough space for an extra 4 floats and so we can safety write q->vals[2] ... q->vals[5], without going over the end of our allocated space. The trick only works for the final memberOf course if vals were not the final member of the structure we would have a serious problem: typedef struct barstr { int n; float vals[2]; int anotherval; } Barstr; The trick would not now work as q->vals[2] would over-write q->anotherval. So the "cheat" array has to be the final member of the strcture for this to work. Flexible arrays in structuresIn fact C allows us to go one stage further than this, a flexible array is an array that is the last member of a structure and has the size omitted: typedef struct flexstr { int n; float vals[]; } Flexstr; The sizeof this structure is the size of the structure assuming an array of zero size and we may then write: Flexstr *q; int nar = 12; q = malloc(sizeof *q + nar * sizeof q->vals[0]); to give us a structure with an array of size nar. Obviously this onlt works for allocated structures, not declared ones, and it's not possible to have an array of such structures as the compiler has no way of knowing where the second one starts. |