Re: Differences between one-dimensional arrays in Java and C



Eric Sosman <esosman@xxxxxxxxxxxxxxxxxxx> writes:

> Tim Rentsch wrote:
> >
> > Now here's an interesting question. I believe it's possible to
> > construct a 2D array (with both dimensions non-constant) by calling
> > malloc only once. For example:
> >
> > [allocate space for elements, padding, and pointers]
> >
> > [yada yada yada]
>
> Looks all right. A type's alignment requirement must be
> a divisor of its size (otherwise arrays wouldn't work), so the
> `extra_space' will be enough padding to get the pointers to
> align properly. In fact, `extra_space' may be more than is
> needed;

Yes it might! Normally the unneed extra space (and even 'extra_space'
itself) won't be too big: I deliberately put the pointer array second
so that at most sizeof(T*)-1 extra space is needed. Usually a few
bytes at most.


> if you really want to be parsimonious you can use a
> dodge that someone posted here a year or two ago:
>
> #include <stddef.h>
> #define alignof(T) offsetof(struct {char c; T t;}, t)
>
> Manually-inserted padding can also be used to write portable
> versions of "the struct hack" for C90 implementations (C99
> introduced an easier notation).

That's a nice trick. I'll definitely have to add that to my set of
arcane C knowledge.

Strictly speaking the definition shown isn't guaranteed to work. If
sizeof(T) is 8 and alignment_of(T) is 2, the result of alignof(T)
might be 2 or 4 or 6, or even 22. Using GCD( alignof(T), sizeof(T) )
should at least produce a result that is guaranteed to work (right?).
But using GCD still isn't enough to guarantee that the minimum
alignment necessary will result.

Furthermore I can envision cases where it might reasonably not yield
the minimum alignment needed; a compiler might choose to put the 't'
member of the struct above at offset 4 (rather than 2) in an attempt
to get better cache performance, for example.

Despite my protestations, a good technique to know. Thanks.
.



Relevant Pages