memcpy problem with padding for word alignment!!! very urgent

N

Ninan Thomas

Hi all
Reading various posts on the newsgroups i was under the impression
that memcpy copy the padding bytes for struct. Apparently it does not
do for me. Here is what i am trying to do

typedef struct DCIClassId {
int size;
unsigned char data; /* place holder for variable length data to follow
the struct*/
}DCIClassId;

this structure is followed by a variable no of integers, which is
stored immediatly after the structure. the size field determines the
number of integers

for example no of integers = size - sizeof(DCIClassId). The memory for
the integers to follow is allocated when the memory is allocated for
the structures

DCIClassId *classId;

cidp = (DCIClassId *)malloc (sizeof(DCIClassId) +
no_of_integers*sizeof(int));

I cannot change the struct definition as it is fixed by the standard
for the product i am working on.

My problem is I want to copy this structure into a character array to
be send over socket and retrieve it. I am using memcpy for it.
char sendmesg[4096]
memcpy(sendmesg + MSGID_SIZE , cidp, classId->size);


/* This is code following theoretically should on another process. But
i tested it also on the same process, to make sure it is not a network
issue.
*/

cidp = (DCIClassId *)malloc(classId->size);
memcpy(cidp, sendmesg + MSGID_SIZE, classId->size);

The integers following the struct are left shifted. and I am not able
to retrieve it. I store three integers following the struct. The
second integer is in the place of the first. The third integer is at
the location of second

I am using gcc 3.2

sizeof(DCIClassId) = 8.

I don't want to use __attribute (pack)__ or some thing similar which
comes with gcc. What is a good portable solution for this issue.

Regards

Ninan
 
P

Paul Pluzhnikov

Reading various posts on the newsgroups i was under the impression
that memcpy copy the padding bytes for struct. Apparently it does not
do for me.

It most certainly does, though this has absolutely nothing to do
with your problem. The padding bytes are *between* the elements
of the struct, not *after* it. What you have is often called
"stretchy array".
stored immediatly after the structure. the size field determines the
number of integers

It is rather difficult to tell what you are doing (are you using
bytes at &cidp->data or not ?).

Post a small self-contained example, and your bug will be revealed
to you.

Cheers,

Followup set to comp.unix.programmer, I think this is off topic
everywhere else.
 
R

Richard Heathfield

[Followups set to comp.lang.c - otherwise we'll be in crosspost hell again
for a week.]

Ninan said:
Hi all
Reading various posts on the newsgroups i was under the impression
that memcpy copy the padding bytes for struct.

It does. You appear to have misunderstood what padding bytes are.
Apparently it does not
do for me. Here is what i am trying to do

typedef struct DCIClassId {
int size;
unsigned char data; /* place holder for variable length data to follow
the struct*/
}DCIClassId;

this structure is followed by a variable no of integers, which is
stored immediatly after the structure. the size field determines the
number of integers

Heh - I can tell what's coming.
for example no of integers = size - sizeof(DCIClassId). The memory for
the integers to follow is allocated when the memory is allocated for
the structures

DCIClassId *classId;

cidp = (DCIClassId *)malloc (sizeof(DCIClassId) +
no_of_integers*sizeof(int));

In C, you can lose the cast. (In C++, you can't.) Dennis Ritchie calls your
technique "unwarranted chumminess with the implementation". Note that you
might want to change char data to char data[1].
I cannot change the struct definition as it is fixed by the standard
for the product i am working on.

Then your product standard is broken (it must be, because the struct
definition is broken!).
My problem is I want to copy this structure into a character array to
be send over socket and retrieve it. I am using memcpy for it.
char sendmesg[4096]
memcpy(sendmesg + MSGID_SIZE , cidp, classId->size);

You've left out a rather crucial piece of information here - the code used
to calculate classId->size.
/* This is code following theoretically should on another process. But
i tested it also on the same process, to make sure it is not a network
issue.
*/

cidp = (DCIClassId *)malloc(classId->size);
memcpy(cidp, sendmesg + MSGID_SIZE, classId->size);

The integers following the struct are left shifted. and I am not able
to retrieve it. I store three integers following the struct. The
second integer is in the place of the first. The third integer is at
the location of second

I am using gcc 3.2

sizeof(DCIClassId) = 8.

I don't want to use __attribute (pack)__ or some thing similar which
comes with gcc. What is a good portable solution for this issue.

You seem to want an array of integers, where you get to choose the number of
integers at runtime.

#include <stdlib.h>

#ifdef __cplusplus
#define SC (int *) /* Spurious cast, for C++ */
#else
#define SC
#endif

typedef struct DCIClassId
{
int *data;
} DCIClassId;

DCIClassId dci = {0};

When you're ready to roll, just do this (if you are in C++, put a cast to
(int *) in place of SC; if you're in C, just leave the useless pointless
program-breaking cast out):

dci.data = SC malloc((n + 1) * sizeof *dci.data);
if(dci.data != NULL)
{
dci.data = n;

At this point, stuff the array with some data.

You can now cheerfully memcpy this stuff as a single block, as follows:

#if NINAN_WANTS_THE_SIZE_INCLUDED_IN_THE_COPY
memcpy(target, dci.data, dci.data[0] * sizeof *dci.data);
#else
memcpy(target, dci.data + 1, (dci.data[0] - 1) * sizeof *dci.data);
#endif
 
K

Kevin Goodsell

Paul said:
It most certainly does, though this has absolutely nothing to do
with your problem. The padding bytes are *between* the elements
of the struct, not *after* it. What you have is often called
"stretchy array".

Padding bytes may and often do come at the end of a struct. This is
necessary to ensure proper alignment for the *first* element of the
struct when you create an array of structs.

It sounds like the OP is using some bizarre variant of the "struct
hack", which relies on undefined behavior and I think is a very bad idea.

-Kevin
 

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

Similar Threads

URGENT 1
memcpy problem 2
Padding on a button for email clients 1
padding struct 3
silly with memcpy() 4
Data alignment questin, structures 46
Structure Size and Padding Byte Questions 2
Alignment problems 20

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top