Optimizing structure memory allocation

R

rahul

How is the memory allocated for structures? I need to optimize the
memory usage and bit fields are not doing the trick.

Any details about the memory allocation for the structures would be a
great help.

PS - I already have asked this in gcc group. Please refrain from
directing me towards other groups.
 
R

Richard Tobin

rahul said:
How is the memory allocated for structures? I need to optimize the
memory usage and bit fields are not doing the trick.

Any details about the memory allocation for the structures would be a
great help.

You'll probably get better help if you ask a more specific question.
Show us what you want to put in the structure.

The members of a struct are stored in the order you specify. Some
members may have types that require a particular alignment, typically
equal to their size. For example, while chars can go anywhere you may
find that if ints are 4 bytes long then they are always placed on
4-byte boundaries. This is common even if the processor allows
arbitrary alignment, because it's usually faster to access
suitably-aligned data.

Suppose shorts are 2 bytes and ints are 4, with corresponding
alignment requirements, and you want to store 2 chars, a short, and an
int in your struct. These could fit in 8 bytes, and will if you order
them correctly, for example

struct foo {
int a;
short b;
char c, d;
};

but if you do

struct foo2 {
char c;
int a;
char d;
short b;
};

it will take 12 bytes, because the 3 bytes after c and the byte after d
are wasted.

If you use bitfields, then you have to consider similar issues at the
bit level. Adjacent bitfields that fit within a "unit" (probably an
int) will be packed together, so don't spread them out amongst other
members of the struct, and try to order them so that they don't go
over too many int boundaries.

-- Richard
 
A

Antoninus Twink

How is the memory allocated for structures? I need to optimize the
memory usage and bit fields are not doing the trick.

PS - I already have asked this in gcc group. Please refrain from
directing me towards other groups.

You might want to look at gcc's packed attribute, which "specifies that
a variable or structure field should have the smallest possible
alignment - one byte for a variable, and one bit for a field, unless you
specify a larger value with the aligned attribute."

You can either pack specific fields, e.g.

struct foo {
char a;
int b __attribute__((packed));
};

or whole structs at once, e.g.

struct bar {
int a;
char b;
int c;
char d;
int e;
} __attribute__((packed));
 
K

Keith Thompson

Antoninus Twink said:
You might want to look at gcc's packed attribute,
[...]

which is, of course, off-topic in comp.lang.c.

rahul, you asked us not to direct you to other groups. Why?
Questions about gcc-specific features are appropriate in gnu.gcc.help;
they are not appropriate in comp.lang.c.

Or you can consult the extensive documentation that comes with gcc.
 
W

Walter Roberson

The members of a struct are stored in the order you specify.

Expanding slightly on Richard's answer for emphasis:

C *requires* that structure members be placed in the order given,
and in increasing address order in memory. Storing the members in
the order coded is not just a matter of convention: it is part
of the language definition. As is the fact that alignment restrictions
exist and are adhered to by the compiler by adding unnamed padding
between structure members if needed (or advised) by the target machine.
 
K

Keith Thompson

Expanding slightly on Richard's answer for emphasis:

C *requires* that structure members be placed in the order given,
and in increasing address order in memory. Storing the members in
the order coded is not just a matter of convention: it is part
of the language definition. As is the fact that alignment restrictions
exist and are adhered to by the compiler by adding unnamed padding
between structure members if needed (or advised) by the target machine.

Right, but it's perfectly legal for the alignment restriction to be
"any alignment is ok". It's also legal (but silly) for the compiler
to insert padding whether it's required for alignment or not.
 
H

Harald van Dijk

Right, but it's perfectly legal for the alignment restriction to be "any
alignment is ok". It's also legal (but silly) for the compiler to
insert padding whether it's required for alignment or not.

It's not silly if older systems required a particular alignment, newer
systems don't, but the compiler still inserts padding to maintain binary
compatibility with those older systems. It's good that implementors are
given a lot of freedom in choosing what works best for their systems.
 
K

Keith Thompson

Eric Sosman said:
The ambiguity lies in "requirement." On one popular
platform, for example, a `double' can be accessed at any
address divisible by four, but can be accessed more quickly
if the address is also divisible by eight. Should the
alignment "requirement" be taken as four or as eight?

Could be either. My point is that the compiler is allowed to insert,
say, 16 bytes of padding, even if it doesn't help performance at all.

It's just an example of the kind of assumption that shouldn't be made
in portable code.
 
R

Richard Tobin

Keith Thompson said:
Could be either. My point is that the compiler is allowed to insert,
say, 16 bytes of padding, even if it doesn't help performance at all.

It's just an example of the kind of assumption that shouldn't be made
in portable code.

I disagree (though obviously only up to a point). It's perfectly
legal for a compiler to insert pointless alignment, but it's also
reasonable to assume that it won't. For example, given any sensible
alignment scheme you will get good packing by ordering members by
decreasing size (int then short then char for example). A portable
program can quite reasonably order structure members on this
assumption, and if it turns out to be false then the blame should be
assigned to the implementation, not the programmer.

We aren't obliged to ignore common sense in our programs, even if
conforming compilers can defeat it.

-- Richard
 
K

Keith Thompson

Eric Sosman said:
Keith said:
Eric Sosman said:
Keith Thompson wrote:
[...] It's also legal (but silly) for the compiler
to insert padding whether it's required for alignment or not.
The ambiguity lies in "requirement." On one popular
platform, for example, a `double' can be accessed at any
address divisible by four, but can be accessed more quickly
if the address is also divisible by eight. Should the
alignment "requirement" be taken as four or as eight?
Could be either. My point is that the compiler is allowed to insert,
say, 16 bytes of padding, even if it doesn't help performance at all.

... and my point was about the word "silly:" Until you
can nail down "requirement" you can't assess the silliness
of the padding scheme.

Ok, good point.

To re-state my point more precisely, a compiler is allowed to insert
padding between struct members even if doing so has no benefit
whatsoever. (I don't know of any compilers that actually do so.)
 
K

Keith Thompson

CBFalconer said:
If you are using gcc, then a gcc group is appropriate. This one is
not. A compiler system can use any method of memory allocation it
pleases, so long as it works.

But the C standard imposes a number of requirements on how memory is
allocated for structures (as we already discussed in this thread).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top