将结构传递给C中的函数

时间:2013-04-18 22:10:41

标签: c

如果我有以下内容: -

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

void baz(struct foo qux)
{

}

我是否认为将bar传递给baz()会导致bar的本地副本被推入堆栈?如果是这样,这是什么类型的副本?在C ++中,我假设它会调用复制构造函数或默认的复制构造函数,但我真的不知道它在C中是如何工作的。

C是否有任何默认复制构造函数的概念,并且它有一个名称吗?可以做些什么来执行深层复制吗? (假设)。我能想到的唯一方法是实际执行深层复制,然后将其传递给函数。

通常,我会将指针传递给foo,但我只是好奇它是如何工作的。此外,我的印象是传递指针更快,节省内存,是执行此类操作时建议的操作过程。我猜它是一个浅拷贝;可以改变吗?

2 个答案:

答案 0 :(得分:4)

  

我是否正确地认为将bar传递给baz()会导致bar的本地副本被推入堆栈?

  

我真的不知道这在C中会起作用。

与C ++中的默认复制构造函数基本相同;复制的每个字段都用原始的相应字段初始化。当然,由于“似乎”规则,整个事情可归结为memcpy

  

我的印象是,传递指针的速度更快,节省了内存,是执行此类操作时建议的操作步骤。

对于较大的struct s,情况往往如此,但并不总是如此;如果你有少量struct的小字段,复制的开销可能会小于间接的开销(同样,使用指针参数可能会很昂贵,因为C和C ++的别名规则可以阻止某些优化)。 / p>

  

我猜它是一个浅拷贝;可以改变吗?

不,浅拷贝(盲目复制每个字段)是默认拷贝构造函数所发生的事情(使用“深拷贝”时,通常也意味着创建指针/引用字段中引用的每个对象的副本)。

你的意思是“通过引用传递”,并不是默认允许最大的灵活性(以及与原始类型的传递一致)。如果你想通过引用传递,你传递一个指针(或C ++中的引用),如果你只是为了性能,通常是const,否则你传递对象本身。

答案 1 :(得分:1)

是的,酒吧的本地副本被推送到堆栈。下面的工作示例评论和休息。

    #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;
    }