Reputation: 9643
Using this guide I was told that arrays are passed by reference. This holds when a struct looks like this:
struct Person{
char* name;
int id;
}
But is doesn't when the struct looks like:
struct Person{
char name[20];
int id;
}
When using the seconds struct, The name
array is copied by value:
struct Person p1 = {"John", 1234};
struct Person p2 = p1;
p2.name[0] = 'L';
// p1.name[0] is still 'K'
Why is this happening?
Upvotes: 4
Views: 3012
Reputation: 1998
In the first case your struct holds a pointer to a buffer of chars, in the second the struct actually contains (read: has space to hold) 20 chars.
So in the first case when you pass by value you are copying the pointer, not the value.
Upvotes: 1
Reputation: 3211
This holds for both. The only difference is that for the first struct you only store the pointer to the string and the id field. In the second struct you store the whole string and the id field in the struct. Therefore the first struct is approx. 8 bytes of size (assuming a 32 bit pointer) and the second struct is approx. 24 bytes of size.
In both cases the whole struct is copied if you call the function and pass it by value. You can check this by modifying the id field instead of the name field.
The reason to pass structs and arrays to functions by reference (as pointer) is to avoid this copy onto stack.
Edit: To clearify: By accessing p2.name[0] for the first struct you access a location outside of the (copied) struct somewhere else in the memory (which is not copied). If you access p2.name[0] for the second struct you access a location inside of the memory area allocated for the (copied) struct.
Reviewing your code I just found another critical part worth noting here: As you are initializing the frist struct with String literals (hard coded strings) writing to p2.name[0] results in undefined behavior (depending on toolchain and operating system your program even could crash because of this!)
Upvotes: 2
Reputation: 183888
I was told that arrays are passed by reference.
That's not quite true. Arrays aren't passed at all, no function can take an array as an argument. When you have a function declared
void foo(int bar[]);
the type of argument that foo
takes is actually int *
, and when you call it
int arr[23];
/* fill arr with meaningful values */
foo(arr);
a pointer to the first element of arr
is passed by value. All function arguments are passed by value in C, without exception.
Thus when you pass a struct Person
to a function, that is passed by value, hence the members of the struct
are copied. If one of the members is an array, that is copied too, since it is a part of the struct
.
Upvotes: 3