 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Guest
|
Posted: Fri Jul 27, 2012 9:52 am Post subject: padding struct |
|
|
Hello Experts,
suppose i have a packet of 9 bytes having fields: length(4bytes), type(1 byte), version(4bytes). Now i would write the packet structure as
struct mypack {
unsigned int;
unsigned char;
unsigned int;
};
when i allocate the structure as:
ptr = (struct mypack *)malloc(sizeof(struct mypack));
the amount of memory allocated is 12bytes(3 bytes extra due to structure padding). If this packet is sent out,how would the receiver receive the correct packet contents, I mean he would know the offset at which each field is present and when he tries to get those field value at that offset he might get it wrong.. for example if he tries to get the 3rd field version which is at offset 6 he would get the wrong value due to the structure padding after char member in struct. how can we solve this? I understand pragma directives avoid padding, but what if I dont want to use them?
Hope I'm clear. Please clarify.
Thanks for your time. |
|
| Back to top |
|
 |
Mark Bluemel Guest
|
Posted: Fri Jul 27, 2012 9:52 am Post subject: Re: padding struct |
|
|
On 27/07/2012 10:52, luvraghu (AT) gmail (DOT) com wrote:
| Quote: | Hello Experts,
suppose i have a packet of 9 bytes having fields: length(4bytes), type(1 byte), version(4bytes). Now i would write the packet structure as
struct mypack {
unsigned int;
unsigned char;
unsigned int;
};
when i allocate the structure as:
ptr = (struct mypack *)malloc(sizeof(struct mypack));
the amount of memory allocated is 12bytes(3 bytes extra due to structure padding). If this packet is sent out,how would the receiver receive the correct packet contents, I mean he would know the offset at which each field is present and when he tries to get those field value at that offset he might get it wrong.. for example if he tries to get the 3rd field version which is at offset 6 he would get the wrong value due to the structure padding after char member in struct. how can we solve this? I understand pragma directives avoid padding, but what if I dont want to use them?
Hope I'm clear. Please clarify.
Thanks for your time.
I think you should read section 2 of the C FAQ. |
Questions 2.11 and 2.12 (including the supplementary information) would
probably help you.
You'll find the FAQ at http://c-faq.com/ |
|
| Back to top |
|
 |
Gordon Burditt Guest
|
Posted: Fri Jul 27, 2012 4:36 pm Post subject: Re: padding struct |
|
|
| Quote: | suppose i have a packet of 9 bytes having fields: length(4bytes),
type(1 byte), version(4bytes). Now i would write the packet structure
as
struct mypack {
unsigned int;
unsigned char;
unsigned int;
};
when i allocate the structure as:
ptr = (struct mypack *)malloc(sizeof(struct mypack));
the amount of memory allocated is 12bytes(3 bytes extra due to
structure padding).
|
You may not portably assume that 12 octets is allocated on the
recipient machine. Note: a C byte is the same size as a C char
by definition, but that might refer to a 32-bit quantity, and does
on some digital signal processors, and might in the future on Unicode
machines. So I'm using "octet" to refer to an 8-bit quantity, not
"byte".
You may not portably assume that an unsigned int is 4 octets (on
16-bit machines it was commonly 2. On a 64-bit machine it might be 8.)
You may not portably assume that an unsigned char is 1 octet (it
might be 4 and that's not including padding).
You may not portably assume that an unsigned int (or even an unsigned
char!) use the same octet-order on both machines.
| Quote: | If this packet is sent out,how would the receiver
receive the correct packet contents,
|
Writing a struct image to a file or over a network is hardly ever
portable, and padding is the least of your worries.
Consider sending an unsigned int, an unsigned char, and an unsigned
int, *NOT* the whole struct. That gets rid of the padding issues.
You *WILL* need to worry about alignment - memcpy() those ints out
of the packet into properly aligned ints. You'd also probably want
to define the number of octets and byte order for everything you
send on the network. Some schemes precede each element with a tag
indicating, for example, "a 4-octet big-endian unsigned integer
follows". Others might use a convention for the protocol that all
multi-byte integers are big-endian in network packets (sender and
receiver are responsible for converting to local-endian).
| Quote: | I mean he would know the offset
at which each field is present and when he tries to get those field
value at that offset he might get it wrong..
|
No, he doesn't necessarily know the (correct) offset. Or size.
| Quote: | for example if he tries
to get the 3rd field version which is at offset 6 he would get the
wrong value due to the structure padding after char member in struct.
how can we solve this? I understand pragma directives avoid padding,
but what if I dont want to use them?
|
pragma directives are unportable, and don't solve the octet-order
and integer size problems. |
|
| Back to top |
|
 |
David T. Ashley Guest
|
Posted: Fri Jul 27, 2012 8:05 pm Post subject: Re: padding struct |
|
|
On Fri, 27 Jul 2012 02:52:27 -0700 (PDT), luvraghu (AT) gmail (DOT) com wrote:
| Quote: | Hello Experts,
suppose i have a packet of 9 bytes having fields: length(4bytes), type(1 byte), version(4bytes). Now i would write the packet structure as
struct mypack {
unsigned int;
unsigned char;
unsigned int;
};
when i allocate the structure as:
ptr = (struct mypack *)malloc(sizeof(struct mypack));
the amount of memory allocated is 12bytes(3 bytes extra due to structure padding). If this packet is sent out,how would the receiver receive the correct packet contents, I mean he would know the offset at which each field is present and when he tries to get those field value at that offset he might get it wrong.. for example if he tries to get the 3rd field version which is at offset 6 he would get the wrong value due to the structure padding after char member in struct. how can we solve this? I understand pragma directives avoid padding, but what if I dont want to use them?
Hope I'm clear. Please clarify.
Thanks for your time.
|
Most aspects of data type storage are machine-dependent and possibly
also compiler-dependent and development-tool-option-dependent.
Usually when data is exchanged between systems (such as via files or
via TCP connection or whatever), there is special code that translates
from the machine-specific format to the exchange format, and also from
the exchange format to the machine format.
This can't be avoided.
DTA |
|
| Back to top |
|
 |
Barry Schwarz Guest
|
Posted: Fri Jul 27, 2012 9:51 pm Post subject: Re: padding struct |
|
|
On Friday, July 27, 2012 4:52:27 AM UTC-5, luvr...@gmail.com wrote:
| Quote: | Hello Experts,
suppose i have a packet of 9 bytes having fields: length(4bytes), type(1 byte), version(4bytes). Now i would write the packet structure as
struct mypack {
unsigned int;
unsigned char;
unsigned int;
};
when i allocate the structure as:
ptr = (struct mypack *)malloc(sizeof(struct mypack));
the amount of memory allocated is 12bytes(3 bytes extra due to structure padding). If this packet is sent out,how would the receiver receive the correct packet contents, I mean he would know the offset at which each field is present and when he tries to get those field value at that offset he might get it wrong.. for example if he tries to get the 3rd field version which is at offset 6 he would get the wrong value due to the structure padding after char member in struct. how can we solve this? I understand pragma directives avoid padding, but what if I dont want to use them?
Hope I'm clear. Please clarify.
Thanks for your time.
|
There is no portable way to eliminate the padding. Your compiler may provide a system specific method of doing so. But does the recipient's?
Furthermore, you have no idea if the padding generated by your compiler will match the padding generated by the recipient's compiler.
You also don't know if the sizeof(int) on your system is the same as the recipient's. The same is true for endianness.
That being said, in my experience most compilers will not generate padding if each of the members is a char or an array of char. Once you construct the values for each member is a set of working variables, you can use a combination of shift operators and bitwise-and operators to construct the members in a documented format. The recipient can use a similar approach to reconstructing the values. |
|
| Back to top |
|
 |
Jorgen Grahn Guest
|
Posted: Sat Jul 28, 2012 8:51 am Post subject: Re: padding struct |
|
|
On Fri, 2012-07-27, luvraghu (AT) gmail (DOT) com wrote:
| Quote: | Hello Experts,
suppose i have a packet of 9 bytes having fields: length(4bytes),
type(1 byte), version(4bytes). Now i would write the packet structure
as
struct mypack {
unsigned int;
unsigned char;
unsigned int;
};
|
My standard answer: don't use structs for I/O. Instead define the I/O
data format in terms of octets (e.g. if this is something UDP-based)
and write functions for filling in/reading from an uint8_t buffer
according to that format.
You can still have a struct, but it won't neccessarily match,
bit-by-bit, the data in your I/O.
Doing the struct-mapping thing IME leads to all kinds of problems:
compiler dependencies, endianness bugs, buffer overflows, weakly
defined data formats, lots of casting, valgrind warnings ...
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o . |
|
| Back to top |
|
 |
Powered by phpBB © 2001, 2006 phpBB Group
|