James Kanze
10/4/2008 8:52:00 AM
On Oct 3, 4:47 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> mojumbo wrote:
> > Problem:
> > I have a structure which needs to store its data in
> > contiguous memory by there is a dynamic element which can't
> > be defined at compile time. It needs to be aligned along a
> > 4 byte boundary. This is what my structure looks like:
> > START
> > struct tsBob
> > {
> > unsigned int fieldA;
> > unsigned int fieldB;
> > unsigned short varLen[0];
> I am not sure this is OK, you might consider giving it at
> least 1 element.
It's not legal C++. Nor legal C, but in C, the last element may
have an incomplete array type, e.g.:
unsigned short varLen[] ;
You can, of course, give the final element a length of 1 in
either language, but then any array access with an index greater
than 0 is undefined behavior.
> > }
> ;
> > tsBob* myBob;
> > myBob = (tsBob*)malloc(sizeof(tsBob) + sizeof(unsigned short) * 1);
> This is better accomplished by the correctly implemented
> 'operator new' in the class itself, and then you just do
> tsBob* myBob = new (true_varLen_count) myBob;
If alignment isn't an issue (and I don't think it can be in his
exact case), then this should be accompanied with:
struct tsBob
{
unsigned short* varLen()
{
return reinterpret_cast< unsigned short* >( this + 1 ) ;
}
} ;
or
struct tsBob
{
unsigned short& operator[]( std::size_t index ) ;
{
// bounds checking...
return reinterpret_cast< unsigned short* >(
this + 1)[ index ] ;
}
} ;
for accessing the additional elements. I'd also do something to
ensure that the actual length was correctly memorized somewhere.
> > END
> > myBob needs an additional 3 bytes alloc'd to it to be aligned. I
> > don't want to use %
> If the size in bytes is divisible by 4, it's going to be
> aligned on the 4 byte boundary. That's the specification of
> 'malloc', IIRC.
No. All that malloc (or operator new()) guarantee is that the
returned pointer is sufficiently aligned for any type. In his
case, he's safe because it's not conceivable that unsigned short
require more alignment than the unsigned int in his struct. In
general, however, you do have to worry about alignment; the
implementation of std::basic_string in g++ uses a similar trick,
and core dumps if you try to use std::basic_string< double > (or
probably std::basic_string< long long >). (Hmmm. I wonder if
there are any platforms where wchar_t is equivalent to a long
long. If so, g++ has a real problem.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34