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

Discussion in 'C++' started by Ninan Thomas, Aug 22, 2003.

  1. Ninan Thomas

    Ninan Thomas Guest

    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
    Ninan Thomas, Aug 22, 2003
    #1
    1. Advertising

  2. (Ninan Thomas) writes:

    > 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.
    --
    In order to understand recursion you must first understand recursion.
    Paul Pluzhnikov, Aug 22, 2003
    #2
    1. Advertising

  3. [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
    Richard Heathfield, Aug 22, 2003
    #3
  4. Paul Pluzhnikov wrote:
    > (Ninan Thomas) writes:
    >
    >
    >>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".


    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
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Aug 22, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ninan Thomas
    Replies:
    3
    Views:
    1,883
    Kevin Goodsell
    Aug 22, 2003
  2. Raymond Arthur St. Marie II of III

    very Very VERY dumb Question About The new Set( ) 's

    Raymond Arthur St. Marie II of III, Jul 23, 2003, in forum: Python
    Replies:
    4
    Views:
    452
    Raymond Hettinger
    Jul 27, 2003
  3. shanx__=|;-

    very very very long integer

    shanx__=|;-, Oct 16, 2004, in forum: C Programming
    Replies:
    19
    Views:
    1,593
    Merrill & Michele
    Oct 19, 2004
  4. Abhishek Jha

    very very very long integer

    Abhishek Jha, Oct 16, 2004, in forum: C Programming
    Replies:
    4
    Views:
    409
    jacob navia
    Oct 17, 2004
  5. Peter

    Very very very basic question

    Peter, Feb 8, 2005, in forum: C Programming
    Replies:
    14
    Views:
    498
    Dave Thompson
    Feb 14, 2005
Loading...

Share This Page