[c] Copying one structure to another

I know that I can copy the structure member by member, instead of that can I do a memcpy on structures?

Is it advisable to do so?

In my structure, I have a string also as member which I have to copy to another structure having the same member. How do I do that?

This question is related to c struct copy

The answer is


If the structures are of compatible types, yes, you can, with something like:

memcpy (dest_struct, source_struct, sizeof (*dest_struct));

The only thing you need to be aware of is that this is a shallow copy. In other words, if you have a char * pointing to a specific string, both structures will point to the same string.

And changing the contents of one of those string fields (the data that the char * points to, not the char * itself) will change the other as well.

If you want a easy copy without having to manually do each field but with the added bonus of non-shallow string copies, use strdup:

memcpy (dest_struct, source_struct, sizeof (*dest_struct));
dest_struct->strptr = strdup (source_struct->strptr);

This will copy the entire contents of the structure, then deep-copy the string, effectively giving a separate string to each structure.

And, if your C implementation doesn't have a strdup (it's not part of the ISO standard), get one from here.


Since C90, you can simply use:

dest_struct = source_struct;

as long as the string is memorized inside an array:

struct xxx {
    char theString[100];
};

Otherwise, if it's a pointer, you'll need to copy it by hand.

struct xxx {
    char* theString;
};

dest_struct = source_struct;
dest_struct.theString = malloc(strlen(source_struct.theString) + 1);
strcpy(dest_struct.theString, source_struct.theString);

You can memcpy structs, or you can just assign them like any other value.

struct {int a, b;} c, d;
c.a = c.b = 10;
d = c;

You can use the following solution to accomplish your goal:

struct student 
{
    char name[20];
    char country[20];
};
void main()
{
    struct student S={"Wolverine","America"};
    struct student X;
    X=S;
    printf("%s%s",X.name,X.country);
}

  1. You can use a struct to read write into a file. You do not need to cast it as a `char*. Struct size will also be preserved. (This point is not closest to the topic but guess it: behaving on hard memory is often similar to RAM one.)

  2. To move (to & from) a single string field you must use strncpy and a transient string buffer '\0' terminating. Somewhere you must remember the length of the record string field.

  3. To move other fields you can use the dot notation, ex.: NodeB->one=intvar; floatvar2=(NodeA->insidebisnode_subvar).myfl;

    struct mynode {
        int one;
        int two;
        char txt3[3];
        struct{char txt2[6];}txt2fi;
        struct insidenode{
            char txt[8];
            long int myl;
            void * mypointer;
            size_t myst;
            long long myll;
             } insidenode_subvar;
        struct insidebisnode{
            float myfl;
             } insidebisnode_subvar;
    } mynode_subvar;
    
    typedef struct mynode* Node;
    
    ...(main)
    Node NodeA=malloc...
    Node NodeB=malloc...
    
  4. You can embed each string into a structs that fit it, to evade point-2 and behave like Cobol: NodeB->txt2fi=NodeA->txt2fi ...but you will still need of a transient string plus one strncpy as mentioned at point-2 for scanf, printf otherwise an operator longer input (shorter), would have not be truncated (by spaces padded).

  5. (NodeB->insidenode_subvar).mypointer=(NodeA->insidenode_subvar).mypointer will create a pointer alias.
  6. NodeB.txt3=NodeA.txt3 causes the compiler to reject: error: incompatible types when assigning to type ‘char[3]’ from type ‘char *’
  7. point-4 works only because NodeB->txt2fi & NodeA->txt2fi belong to the same typedef !!

    A correct and simple answer to this topic I found at In C, why can't I assign a string to a char array after it's declared? "Arrays (also of chars) are second-class citizens in C"!!!


In C, memcpy is only foolishly risky. As long as you get all three parameters exactly right, none of the struct members are pointers (or, you explicitly intend to do a shallow copy) and there aren't large alignment gaps in the struct that memcpy is going to waste time looping through (or performance never matters), then by all means, memcpy. You gain nothing except code that is harder to read, fragile to future changes and has to be hand-verified in code reviews (because the compiler can't), but hey yeah sure why not.

In C++, we advance to the ludicrously risky. You may have members of types which are not safely memcpyable, like std::string, which will cause your receiving struct to become a dangerous weapon, randomly corrupting memory whenever used. You may get surprises involving virtual functions when emulating slice-copies. The optimizer, which can do wondrous things for you because it has a guarantee of full type knowledge when it compiles =, can do nothing for your memcpy call.

In C++ there's a rule of thumb - if you see memcpy or memset, something's wrong. There are rare cases when this is not true, but they do not involve structs. You use memcpy when, and only when, you have reason to blindly copy bytes.

Assignment on the other hand is simple to read, checks correctness at compile time and then intelligently moves values at runtime. There is no downside.


Examples related to c

conflicting types for 'outchar' Can't compile C program on a Mac after upgrade to Mojave Program to find largest and second largest number in array Prime numbers between 1 to 100 in C Programming Language In c, in bool, true == 1 and false == 0? How I can print to stderr in C? Visual Studio Code includePath "error: assignment to expression with array type error" when I assign a struct field (C) Compiling an application for use in highly radioactive environments How can you print multiple variables inside a string using printf?

Examples related to struct

How to search for an element in a golang slice "error: assignment to expression with array type error" when I assign a struct field (C) How to set default values in Go structs How to check for an empty struct? error: expected primary-expression before ')' token (C) Init array of structs in Go How to print struct variables in console? Why Choose Struct Over Class? How to return a struct from a function in C++? Initializing array of structures

Examples related to copy

Copying files to a container with Docker Compose Copy filtered data to another sheet using VBA Copy output of a JavaScript variable to the clipboard Dockerfile copy keep subdirectory structure Using a batch to copy from network drive to C: or D: drive Copying HTML code in Google Chrome's inspect element What is the difference between `sorted(list)` vs `list.sort()`? How to export all data from table to an insertable sql format? scp copy directory to another server with private key auth How to properly -filter multiple strings in a PowerShell copy script