question on struct.calcsize

John Machin sjmachin at lexicon.net
Thu Mar 28 16:35:13 EST 2002


stojek at part-gmbh.de (Marcus Stojek) wrote in message news:<3ca33d3f.26101031 at news.easynews.net>...
> Hi,
> could anyone explain the following, please.
> (Win NT, Python 2.1.1)
> 
> >>> from struct import *
> >>> calcsize("i")
>  4
> >>> calcsize("s")
>  1
> >>> calcsize("si")
> 8

Simply, the int is being aligned on the next available 4-byte
boundary. See below.
>>> from struct import *
>>> for n in range(10):
...    fmt_str = '%dsi' % n
...    print fmt_str, calcsize(fmt_str)
...
0si 4
1si 8
2si 8
3si 8
4si 8
5si 12
6si 12
7si 12
8si 12
9si 16
>>>

If you are designing the struct yourself and you want to cut down on
wasted memory, list out the structure members in descending order of
size -- int, byte, byte will take the space of 2 ints whereas byte,
int, byte will take the space of 3 ints. Other things to bear in mind:
a 64-bit machine may well have an 8-byte alignment requirement;
malloc(n) generally rounds up the space taken to K times the alignment
requirement, where K can be > 1; and specifically for small n, malloc
may use a greater K -- for example malloc(1) could chew up as much
memory as malloc(16). End result: you often have "spare" memory at the
end of your struct; packing a small int into a byte may save no memory
and may in fact be slower to access on some architectures.

Don't try to fight the alignment and get an int starting at offset 1.
On some architectures you will get an address violation; on most
others accessing such an int would be much slower than accessing an
aligned int.

OTOH, if the struct is already specified, you need to look very
carefully at whether you want "native" alignment (what you have by
default in your example) [the calculations are done for you but the
answers vary by platform] or "standard" alignment [which really means
no assistance with alignment; you have to put "x" pad bytes in the
format string yourself] -- read the docs. If the producer and consumer
are on different platforms, you need a carefully-designed
standard-alignment struct or, better, use a higher-level-than-C-struct
data interchange protocol.

... and that *was* the SHORT answer :-)

HTH,
John



More information about the Python-list mailing list