[Followups set to comp.lang.c - otherwise we'll be in crosspost hell again
for a week.]
Ninan Thomas wrote:
> 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
--
Richard Heathfield :
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ:
http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc:
http://users.powernet.co.uk/eton