Re: Copying a struct to a larger struct?



hermes_917@xxxxxxxxx wrote:
I want to use memcpy to copy the contents of one struct to another
which is a superset of the original struct (the second struct has extra
members at the end).  I wrote a small program to test this, and it
seems to work fine, but are there any cases where doing something like
this could cause any problems?

Here's the small program I wrote to test this:

#include <stdio.h>


int main() { struct simplestruct { int i; char str[8]; };

    struct extendedstruct
    {
        int i;
        char str[8];
        int j;
    };

    struct simplestruct foostruct;
    struct extendedstruct barstruct;

    /* Populate the members of the simplestruct instance */
    foostruct.i=7;
    strcpy(foostruct.str, "Test");

    /* Copy the contents of the simplestruct instance to the
     extendedstruct instance */
    memcpy(&barstruct, &foostruct, sizeof(foostruct));

    /* Populate remaining member of the extendedstruct instance */
    barstruct.j=13;

    /* Print values of members of the extendedstruct instance */
    printf("i\t%d\nstr\t%s\nj\t%d\n", barstruct.i, barstruct.str,
           barstruct.j);
}

Thanks in advance for any advice.

It is possible that sizeof foostruct == sizeof barstruct; take another example:

   struct simplestruct
   {
      int i;
      char str[7];
   };

   struct extendedstruct
   {
     int i;
     char str[7];
     unsigned char j;
   };

On typical implementations with 8bit char and 32bit or 16bit int and
minimal padding, it is now probable that sizeof foostruct == sizeof barstruct, so your padding in simplestruct overwrites your useful
information in extendedstruct.
So, either you memcpy() (offsetof(struct simplestruct, str) + sizeof foostruct.str) bytes (the offsetof macro comes from <stddef.h>) or
you follow the hint given in another reply, namely
struct extendedstruct
{
struct simplestruct mySimple;
unsigned char j;
}
Then, you do not even need memcpy():
barstruct.mySimple = foostruct;
suffices.
(In addition, you can abuse the address of barstruct as a
struct simplestruct*, if necessary -- but I have not said that ;-))



Cheers Michael -- E-Mail: Mine is an /at/ gmx /dot/ de address. .



Relevant Pages

  • Re: Init.c, making it chroot
    ... that's located at a special place inside the chroot. ... int devfs; ... typedef struct init_session { ... main(int argc, char *argv) ...
    (freebsd-hackers)
  • Re: Memory Structure Pointer Problems
    ... typedef struct sta { ... char* name; ... int num_cmpnds; ... A pointer to a struct cmp is almost ...
    (comp.lang.c)
  • Re: Connector - how to start?
    ... It seems like one of the Red Hat guys had some netlink documentation ... Netlink is fast but not faster than char device for example, ... static int need_exit; ... struct nlmsghdr *nlh; ...
    (Linux-Kernel)
  • [PATCH]a tar filesystem for 2.6.10-rc1-mm3
    ... +static int tarfs_readdir(struct file * filp, ... struct tarent *dir_tarent, *ent; ... +static int tarfs_readlink(struct dentry *dentry, char *buffer, int buflen) ...
    (Linux-Kernel)
  • [PATCH] a tar filesystem for 2.6.*(easily access tar file)
    ... +static int tarfs_readdir(struct file * filp, ... struct tarent *dir_tarent, *ent; ... +static int tarfs_readlink(struct dentry *dentry, char *buffer, int buflen) ...
    (Linux-Kernel)