Tom
Tom

Reputation: 9643

array of struct is passed by value rather than reference

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

Answers (3)

tletnes
tletnes

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

junix
junix

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

Daniel Fischer
Daniel Fischer

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

Related Questions