On Sun, Jan 06, 2002 at 04:48:24PM -0800, Eric G. Miller wrote: | On Sun, 6 Jan 2002 16:48:31 -0500 (EST), William T Wilson <[EMAIL PROTECTED]> wrote: | | > On Sat, 5 Jan 2002, Eric G.Miller wrote: | > | > > is one of the reasons pointers to char are so common. However, there | > > is a little trick that's guaranteed to always work: | > > | > > struct foo { | > > size_t length; | > > char str[1]; | > > }; | > > | > > ... | > > | > > struct foo * str_to_foo(char *a) | > > { | > > size_t len = strlen (a); | > > struct foo *bar = malloc (sizeof(struct foo) + len); | > > if (bar) { | > > bar->length = len; | > > memcpy (bar->str, a, len); /* bar->str now not NUL terminated */ | > > } | > > return bar; | > > } | > | > It doesn't look particularly guaranteed to me. | | > You're really allocating *three* pieces of memory here - one for | > the struct foo, one for the 1-character array chr, and one for the | > rest of the string.
One piece -- there is only 1 malloc() call. | > Your example assumes that chr will be located in memory | > immediately after foo - which it probably will, but it might not. | > It could be anywhere, the language makes no guarantee. The | > compiler might even choose to put the 1-char array before foo, so | > you can't use it without overwriting your struct Good thought, but I think Eric is right here | It *is* one chunk of memory, and it does work. The compiler is not allowed | to reorder the members of the struct. A pointer to the struct is always | guaranteed to be a pointer to the first element, as well. GTK+ achieves inheritance by (ab)using this feature. Example : struct Base { int member1 ; } struct Child { struct Base b ; int member2 ; } you can then case a Child* to a Base* and it will work. (their macros that do the casting for you do some sort of check first though) | The compiler may add padding between elements of the struct for | alignment purposes, but we don't need to care about that | (sizeof(struct foo)) will do the right thing. If you don't believe | me, ask the guru's on comp.lang.c. This extra space allocation for | structs trick, only works for the last member of the struct | (obviously), and it should be declared as an array with one element | (it's not limited to char's). Though technically that 'len' should be multiplied by 'sizeof(char)' just for safety/clarity (even though sizeof(char) is 1). | > > The benefit is being able to use one malloc vs. two (for any similarly | > | > This is a benefit why? :} | | Calls to malloc are relatively expensive. It's more efficient to use | fewer large allocations than many small ones. Also, makes management | of the memory a little simpler (only one chunk of memory to worry about). I was thinking of the redundancy of calling realloc() shortly after calling malloc(), but I had something different (but not wholly clear) in mind. -D -- Consider what God has done: Who can straighten what He has made crooked? Ecclesiastes 7:13