Assign structure with char array inside using "="?

I look at the code for someone, and the developer assigned one structure to another. The structure contains a char array. One way or another, that β€œworks”, which means that the char array from structure A will be copied to structure B (not by reference). I am completely baffled. Maybe so explain it to me? I wrote a small program to illustrate the β€œproblem”.

#include <stdio.h> #include <string.h> /************************************** * some define and typedef for later **************************************/ #define MAX_LEN (80) typedef struct month_s { char name[MAX_LEN]; } month_st; /************************************** * This bit is clear. **************************************/ static void usingString() { char mCur[MAX_LEN] = {"Jan"}; char mNext[MAX_LEN] = {"Feb"}; /** this doesn't compile (of course) */ //mCur = mNext; /** we need a pointer/reference */ char *pmCur = &mCur[0]; /** however now we "copy by reference"...*/ pmCur = &(mNext[0]); /** ...so this change also applies to pmCur*/ strcpy(mNext, "Mar"); /** ...so pmCur is now "Mar"*/ printf("%s: %s\n", __func__, pmCur); } /************************************** * I though the same/s.th. similar * as above happens here. But this "works". * I'm surprised to see that not to be * the case. Can someone explain? **************************************/ static void usingStruct() { month_st mCur = {"Jan"}; month_st mNext = {"Feb"}; /** I would have thought this is "copy by reference" for the string! */ mCur = mNext; /** I would have thought this also overrides mCur.name 'cause it pointing to mNext.name now */ strcpy(mNext.name, "Mar"); /** how come this works??? mCur.name is still "Feb"*/ printf("%s: %s\n", __func__, mCur.name); } /************************************** * just the main() **************************************/ int main() { usingString(); usingStruct(); return 0; } 
+4
source share
4 answers

I see three explanations for the differences between pointers and arrays, but they don't seem to address the question I'm asking, as far as I understand.

The question, as I understand it, is this: "I know that I cannot assign one array to another, so why can I do this if the array is inside the structure?"

The answer is basically "because the language said so." Although a structure is an aggregated type and can contain an array, the language specification says that structures are assigned, and therefore structures can be assigned. This is 6.5.16.1 Simple assignment section in N1256 and N1570 .

(Under the hood, the compiler may have to implement a copy of memory, but the problem is with the compiler, not yours.)

+2
source

What you are probably most surprised at is that arrays and pointers are not the same thing in C. The array element, as in your example, contains not only a pointer to a string, but also the string itself. Thus, all abstracts are copied when you assign one instance of struct another.

+3
source

According to your structure declaration:

 typedef struct month_s { char name[MAX_LEN]; } month_st; 

sizeof(month_st) contains spaces for the char array, which is a member of the structures. (Note that you are doing a static memory allocation, name not a pointer, but an array).
Therefore, when you assign one strct variable to another variable, it completely copies the array (or we can say that the total number of bytes sizeof(month_st)) will be copied).

Then you declare two structural variables:

 month_st mCur = {"Jan"}; month_st mNext = {"Feb"}; 

The memories for both mCur and mNext different. When you do the assignment nCur = mNext; , mNext values mNext copied into nCur memory of struct variables, but both have separate (their) memory.

strcpy() :

 strcpy(mNext, "Mar"); 

affecting only the mNext variable, it does not change the contents of the nCur variable.

For your confusion, suppose you declare your structure as follows:

 typedef struct month_s { char* name; } month_st; 

However, by doing nCur = mNext; , you copy sizeof(month_st)) bytes from the mNext variable to nCur , therefore, only the address copied as name is a pointer to memory.

In this case, the full array / memory (which you probably allocate dynamically), do not copy this, called Shallow copy .

+1
source

You are confused because you think that mCur and mNext are pointers to objects, whereas in reality they are objects. The month_s structure simply allocates memory space for storing the month name. It does not allocate memory to hold a pointer to anything. Thus, when mCur assigned the value mNext , the entire object is copied because it is copied by value, not by reference.

I requested the code for convenience:

 static void usingStruct() { month_st mCur = {"Jan"}; month_st mNext = {"Feb"}; /** mCur and mNext are both objects. Assigning one to the other * will copy by value and not by reference (as there is no reference * to be copied in the first place). After this assignment, * mCur == {"Feb"} */ mCur = mNext; /** mNext.name is the address of the memory allocated to the object * mNext. This line copies the characters "Mar" to the first three * bytes of this memory allocation */ strcpy(mNext.name, "Mar"); /** At this point, mCur == {"Feb"} and mNext == {"Mar"} */ printf("%s: %s\n", __func__, mCur.name); } 
0
source

Source: https://habr.com/ru/post/1493805/


All Articles