The said:
Christopher Benson-Manica wrote:
"I came across some code that declared a structure like this:
struct name {
int namelen;
char namestr[1];
};
and then did some tricky allocation to make the namestr array act like it had
several elements."
Exactly what kind of "tricky allocation" is the FAQ talking about?
Allocating memory for the struct "plus:"
struct name *ptr;
ptr = malloc(offsetof(struct name, namestr) + strlen(name) + 1);
I've the FAQ not by hand now, but I don't think that this _bug_ will
be in there.
If there's a _bug_ present, it's still escaping my notice.
malloc(*ptr+strlen(name)) or maybe malloc(sizeof(struct
name)+strlen(name))
is the right answer.
The first suggestion won't compile,
Typing error: malloc(sizeof(*ptr)+..... should be written.
because the `+' operator
cannot use a struct type as an operand. The second will work,
but may allocate more space than necessary.
No it allocates exactly the needed memory. Yes, as a struct may have
some padding bytes at its end to get the next address a pointer to
struct can point to without failing on the CPU.
Whenever the compiler determines it has to do some paddings between
the int and the char[] you'll lost. Whenever you've to change the
struct by inserting some new member before the incomplete array you'll
lost too.
I think you've failed to understand what `offsetof' does.
No, but why make code coplicated? Is building a char pointer from a
struct, adding the difference in bytes to an member of a struct
casting it then to another type better than using simply the ptr->name
or ptr->namestr or ptr->newmember?
Write a program that has to access that struct in 3.000 transation
units in different places, then insert a new member into the struct,
then find any place in any translation unit that accesses the struct.
Is moth of retesting the whole application then worth to save some
bytes?
You may ever do this when you have to crypt the sources - but when you
were my (or ever employyer I've ever worked for) employee you would
get fired before you were ready with a single translation unit.
Using a byte array without any structure would be more clean then. Why
does you use a struct? You needs/likes to document your code! Handling
with casing pointers from type to type only to get access to a member
of a struct is crazy.
Even as it is a common trick to set an array[1] as placeholder for a
variable lenth string on the end of of a struct to save the space for
a pointer (and subsequent malloc()s to get a dynamic address to a
dynamic sized array it is noways a need to misuse the whole struct and
play with castings to pointers to make an addition to recaste the
pointer only to get a single member from that struct.
When you likes such games then you should read/store each
int/short/char/float/pointer and all other datatypes byte by byte,
using an unnamed array of bytes to store them - but not a struct. Then
you can win some more bytes when you allocs simply a big block on
memory and does the full housekeeping on it by hand. Then you can be
sure to avoid any padding byte. But the readability of your code
shrinks to zero, nil, void, nada. And the code will completely
unmaintenanceable. And you have to spend the volume you saves in data
in code and the time the program needs to do what it has to do
increases significantly. In extreme it would need a multiple on time
to load or save information there as it needs to do the work it is
designed for.