Structure padding
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > Structure padding




Pages (4): [1] 2 3 4 »   Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    Structure padding  
Russell Shaw


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-14-05 10:56 PM

Hi,

In a memory manager i wrote, i get corruption somewhere from
newly malloced (gnu malloc) memory overwriting existing heap variables.

I have:

----------------------------------------------------------------------------
#include<stddef.h>

#define DATA_PTR_FROM_BLOB(blob)    ((void*)(blob) + offsetof(Blob, data))

#define BLOB_FROM_DATA_PTR(ptr)    ((void*)(ptr) - offsetof(Blob, data))

typedef struct Blob {
int magic;
size_t payloadsize;
unsigned char data[0];
struct Blob *next, *prev; // overwritten by payload starting at data[0]
} Blob;
----------------------------------------------------------------------------

Macro offsetof() comes from stddef.h (gcc 4.0.3 on debian linux).

I've been doing:

struct Blob ablob;
..
void *dataptr = DATA_PTR_FROM_BLOB(ablob);
..
Blob *blobheader = BLOB_FROM_DATA_PTR(dataptr);
..

Will this have alignment problems with gaps in the Blob struct?





[ Post a follow-up to this message ]



    Re: Structure padding  
Paul Pluzhnikov


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-14-05 10:56 PM

Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:

> In a memory manager i wrote, i get corruption somewhere from
> newly malloced (gnu malloc) memory overwriting existing heap variables.

If the corruption is reproducible, the easiest way to catch it is
with data breakpoint. On P3 and above, gdb implements data
breakpoints via (hardware) debug registers, and they are very fast.

> #define DATA_PTR_FROM_BLOB(blob)    ((void*)(blob) + offsetof(Blob, data))
> #define BLOB_FROM_DATA_PTR(ptr)    ((void*)(ptr) - offsetof(Blob, data))

Pointer arithmetic on 'void *' is non-portable.
Quick, which of the two expressions below is true?

((void *)p + 1) == ((char *)p + 1)
((void *)p + 1) == ((int *)p + 1)

>    Blob *blobheader = BLOB_FROM_DATA_PTR(dataptr);
>
> Will this have alignment problems with gaps in the Blob struct?

No. The offsetof() takes care of accounting for them.

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.





[ Post a follow-up to this message ]



    Re: Structure padding  
Ben Pfaff


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-14-05 10:56 PM

Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:

> In a memory manager i wrote, i get corruption somewhere from
> newly malloced (gnu malloc) memory overwriting existing heap variables.
>
> typedef struct Blob {
>     int magic;
>     size_t payloadsize;
>     unsigned char data[0];
>     struct Blob *next, *prev; // overwritten by payload starting at data&#
91;0]
> } Blob;

You declared data[] as having 0 elements.  Thus, it overlaps with
next and prev.  (Is this really a surprise?)

ANSI C doesn't allow 0-element arrays.  You must be using some
compiler extension.

I recommend moving data[] to the end of the struct.
--
Ben Pfaff
email: blp@cs.stanford.edu
web: http://benpfaff.org





[ Post a follow-up to this message ]



    Re: Structure padding  
Keith Thompson


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-14-05 10:56 PM

Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:
> In a memory manager i wrote, i get corruption somewhere from
> newly malloced (gnu malloc) memory overwriting existing heap variables.
>
> I have:
>
> --------------------------------------------------------------------------
--
> #include<stddef.h>
>
> #define DATA_PTR_FROM_BLOB(blob)    ((void*)(blob) + offsetof(Blob, data))
>
> #define BLOB_FROM_DATA_PTR(ptr)    ((void*)(ptr) - offsetof(Blob, data))
>
> typedef struct Blob {
>      int magic;
>      size_t payloadsize;
>      unsigned char data[0];
>      struct Blob *next, *prev; // overwritten by payload starting at data&
#91;0]
> } Blob;
> --------------------------------------------------------------------------
--
>
> Macro offsetof() comes from stddef.h (gcc 4.0.3 on debian linux).
>
> I've been doing:
>
>    struct Blob ablob;
>    ...
>    void *dataptr = DATA_PTR_FROM_BLOB(ablob);
>    ...
>    Blob *blobheader = BLOB_FROM_DATA_PTR(dataptr);
>    ...
>
> Will this have alignment problems with gaps in the Blob struct?

The use of a zero-element array is not allowed in standard C.  There's
a more nearly conforming version declares a 1-element array, but
allocates more memory so elements past the end of the array can be
accessed; this is known as the "struct hack".  See
<http://www.eskimo.com/~scs/C-faq/q2.6.html> for more information.

But the array must be the last declared member of the struct;
otherwise it will write over any following members.

C99 adds, and I'm fairly sure gcc supports, a conforming version of
the struct hack known as the "flexible array member".  The declaration
uses empty brackets rather than the fictitious [0] or [1]:
unsigned char data[];
Search the gcc documentation, or a recent C reference, for "flexible
array member".

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center             <*>  <http://users.sdsc.edu/~kst>
We must do something.  This is something.  Therefore, we must do this.





[ Post a follow-up to this message ]



    Re: Structure padding  
Steve O'Hara-Smith


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-15-05 07:51 AM

On Tue, 15 Nov 2005 03:31:52 +1100
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> wrote:
[vbcol=seagreen]
> typedef struct Blob {
>      int magic;
>      size_t payloadsize;
>      unsigned char data[0];
>      struct Blob *next, *prev; // overwritten by payload starting at data[0][/
vbcol]

Well yes and if the payload size is greater than the size of the
two pointers something else is going to get overwritten and you have no
idea what that something else will be.

--
C:>WIN                                      |   Directable Mirror Arrays
The computer obeys and wins.                | A better way to focus the sun
You lose and Bill collects.                 |    licences available see
|    http://www.sohara.org/





[ Post a follow-up to this message ]



    Re: Structure padding  
slebetman@yahoo.com


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-15-05 07:51 AM

Russell Shaw wrote:
> Hi,
>
> In a memory manager i wrote, i get corruption somewhere from
> newly malloced (gnu malloc) memory overwriting existing heap variables.
>
> I have:
>
> --------------------------------------------------------------------------
--
> #include<stddef.h>
>
> #define DATA_PTR_FROM_BLOB(blob)    ((void*)(blob) + offsetof(Blob, data))
>
> #define BLOB_FROM_DATA_PTR(ptr)    ((void*)(ptr) - offsetof(Blob, data))
>
> typedef struct Blob {
>      int magic;
>      size_t payloadsize;
>      unsigned char data[0];
>      struct Blob *next, *prev; // overwritten by payload starting at data&
#91;0]
> } Blob;
> --------------------------------------------------------------------------
--
>
> Macro offsetof() comes from stddef.h (gcc 4.0.3 on debian linux).
>
> I've been doing:
>
>    struct Blob ablob;
>    ...
>    void *dataptr = DATA_PTR_FROM_BLOB(ablob);
>    ...
>    Blob *blobheader = BLOB_FROM_DATA_PTR(dataptr);
>    ...
>
> Will this have alignment problems with gaps in the Blob struct?

Others have already explained this, but just to make it clear I think
what you want is this:

typedef struct Blob {
int magic;
size_t payloadsize;
struct Blob *next, *prev;
unsigned char data[0];
} Blob;

Happened to me once when I had to add a member to my struct. Always
declare stuff BEFORE the data section. Otherwise the member variable
and data will corrupt each other.






[ Post a follow-up to this message ]



    Re: Structure padding  
Paul Pluzhnikov


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-15-05 07:51 AM

"slebetman@yahoo.com" <slebetman@gmail.com> writes:

> Others have already explained this, but just to make it clear I think
> what you want is this:

He probably doesn't. When writing a memory manager, it is a *very*
common technique to have a "Blob" either allocated, or on the
free-list.

Thus it makes sense to share the storage for forward/back links and
the user data, because either one or the other is used at any given
moment, but never both at the same time.

I think the OP did this *intentionally* (and provided a comment
stating this intent), and everybody who pointed out that data[]
would overwrite the links missed the point. But only the OP can
say for sure.

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.





[ Post a follow-up to this message ]



    Re: Structure padding  
Russell Shaw


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-15-05 12:54 PM

Ben Pfaff wrote:
> Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:
> 
>
> You declared data[] as having 0 elements.  Thus, it overlaps with
> next and prev.  (Is this really a surprise?)
>
> ANSI C doesn't allow 0-element arrays.  You must be using some
> compiler extension.

I'm using "data" as an empty marker for the first free memory location follo
wing
that point. Anything written starting at "data" will overwrite next/prev,
and extend outside the struct. It's a bit like using alloca(0), but i'm doin
g
it on the heap.

> I recommend moving data[] to the end of the struct.





[ Post a follow-up to this message ]



    Re: Structure padding  
Russell Shaw


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-15-05 12:54 PM

Keith Thompson wrote:
> Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:
> 
>
> The use of a zero-element array is not allowed in standard C.  There's
> a more nearly conforming version declares a 1-element array, but
> allocates more memory so elements past the end of the array can be
> accessed; this is known as the "struct hack".  See
> <http://www.eskimo.com/~scs/C-faq/q2.6.html> for more information.

I'm using a gcc extension for zero length arrays.

> But the array must be the last declared member of the struct;
> otherwise it will write over any following members.

When Blob is taken out of storage for use, user data starts at "data",
overwriting next/prev pointers. Those pointers are only used when the
blob is back in the pool, so 8 bytes are gained for free during use.

> C99 adds, and I'm fairly sure gcc supports, a conforming version of
> the struct hack known as the "flexible array member".  The declaration
> uses empty brackets rather than the fictitious [0] or [1]:
>     unsigned char data[];
> Search the gcc documentation, or a recent C reference, for "flexible
> array member".

5.11 in gcc-4.0 info explains it. Unfortunately, it says:

* Flexible array members may only appear as the last member of a
`struct' that is otherwise non-empty.





[ Post a follow-up to this message ]



    Re: Structure padding  
Russell Shaw


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-15-05 12:54 PM

Ben Pfaff wrote:
> Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:
> 
>
> You declared data[] as having 0 elements.  Thus, it overlaps with
> next and prev.  (Is this really a surprise?)
>
> ANSI C doesn't allow 0-element arrays.  You must be using some
> compiler extension.

I'm using gcc-4. I don't see why they should disallow empty array decs.,
because it's good for marking a memory location used for variable size
storage.

> I recommend moving data[] to the end of the struct.





[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 04:24 PM.      Post New Thread    Post A Reply      
Pages (4): [1] 2 3 4 »   Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register