简体   繁体   中英

Passing a struct to a function in C

If I have the following: -

struct foo
{
  int a;
  int *b;
} bar;

void baz(struct foo qux)
{

}

Am I right in thinking that passing bar to baz() results in a local copy of bar being pushed onto the stack? If so, what kind of copy is this? in C++, I assume it would call the copy constructor, or the default copy constructor but I don't really know how this would work in C.

Does C have any notion of a default copy constructor and does this have a name? Could something be done to perform a deep copy? (hypothetically). The only way I could think of is to actually do a deep copy and then pass it to the function.

Typically, I would be passing a pointer to a foo but I'm just curious as to how it is working. Furthermore I am under the impression that passing a pointer is faster, saves memory and is the recommended course of action to take when doing this kind of operation. I would guess that it is a shallow copy; can this be changed?

Am I right in thinking that passing bar to baz() results in a local copy of bar being pushed onto the stack?

Yes.

I don't really know how this would work in C.

Substantially as it would with the default copy constructor in C++; every field of the copy is initialized with the corresponding field of the original. Of course, because of the "as if" rule the whole thing may boil down to a memcpy .

I am under the impression that passing a pointer is faster, saves memory and is the recommended course of action to take when doing this kind of operation.

For larger struct s it's often the case, but it's not always like that; if you have a small struct of few small fields the overhead of copying will probably be smaller than that of indirection (also, using pointer parameters can be costly because the aliasing rules of C and C++ can prevent some optimizations).

I would guess that it is a shallow copy; can this be changed?

No, a shallow copy (blindly copy each field) is what happens with the default copy constructor (while with "deep copy" you usually mean also creating a copy of each object referenced in pointer/reference fields).

What you mean is "pass by reference", and it's not the default to allow the maximum flexibility (and for coherency with the passing of primitive types). If you want pass by reference you pass a pointer (or a reference in C++), often const if you are in just for the performance, otherwise you pass the object itself.

Yes a local copy of bar is pushed on to the stack. and rest is commented on following working example.

    #include <stdio.h>
    struct foo
    {
        int a;
        int *b;
    } bar;
    void baz(struct foo qux)
    {
        bar.a = 2; // if its a different copy then printf on main should print 1 not 2.
        *bar.b = 5; // if its a different copy then printf on main should print 5 not 4. since the place pointer pointing to is same
    }
    int main(){
        bar.a=1;
        bar.b = (int*)malloc(sizeof(int));
        *bar.b = 4;
        baz(bar); // pass it to baz(). now the copy of bar in the stack which is what baz going to use
        printf("a:%d | b:%d\n",bar.a,*bar.b);
        //answer is  2 and 5
        /*So indeed it does a shallow copy thats why we lost the "4" stored in bar.b it did not created new space in heap to store "5" instead it used the same space that b was pointing to.
        */
    return 0;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM