函数参数值与参考内存管理

时间:2015-04-07 22:56:18

标签: c memory-management

我试图理解C语言,更具体地说是关于内存管理。我有一个函数func,它接受​​一个参数,一个int指针。如果我使用int i而不是int *i,则会分配更多内存,因为该值将被复制。由于我知道func1func2都不会更改i变量,因此这两个函数的结果完全相同。

如果我多次调用这些函数会怎么样?显然func1表现更好,更正确吗?那么func2呢?它会在每次调用时分配新的内存吗?那么分配10000 * 4个额外字节?还是只需4个字节?

我想它会分配4个额外的字节,如果它实际上是,这个内存何时分配?它是在第一次调用函数时吗?此外,这4(?)字节的内存如何以及何时变为空闲?

void func1(int *i)
{
}

void func2(int i)
{
}

void main()
{
    int x = 100;
    for(int i = 0; i < 10000 ; i++) func1(&x);
    for(int i = 0; i < 10000 ; i++) func2(x);
}

4 个答案:

答案 0 :(得分:2)

这可能是特定于编译器的(您可以查看C规范以确定),但是应该在函数的调用堆栈上分配整数参数。每次调用该函数时,都会分配额外的4个字节,以便在函数返回时释放。

对于函数的引用版本,它将在每个函数调用上为int指针分配空间。根据您的机器,可能更大,更小或与int相同。将sizeof(int)sizeof(int*)进行比较,看看哪个更大。

答案 1 :(得分:2)

让我们来谈谈存储持续时间,它是由变量命名的对象(执行环境中的数据存储区域,其内容可以表示值)的持续时间。没有显式存储持续时间或存储持续时间autoregister的函数参数和局部变量具有自动存储持续时间。也就是说,它们是在声明时创建的,并在它们被销毁时创建包含它们的函数返回。

在函数调用中,为参数指定的值将复制到表示函数定义中的参数的自动变量中。这些变量在函数返回时被销毁,所以除非你递归地调用自己,否则你不会积累大量的内存。你不应该关心intint*的大小之间的差异,除非你有很多这些。如有疑问,请在发现问题时查看并更改代码。

答案 2 :(得分:1)

C标准没有指定参数的传递方式,但是,在大多数C实现中,参数使用的内存会在调用堆栈上自动分配和释放,与堆分配相比,这几乎没有开销。通常,在传递参数时,在堆栈上分配内存,并在函数返回之前或之后释放。

两个版本的函数都会在调用堆栈上分配内存。参考版本将为指针分配内存。参考版本可能更慢,因为它涉及指针解除引用。

答案 3 :(得分:1)

由于过度简化的风险和实际可行的实施,一般没有性能或内存差异

void func1(int *i)
void func2(int i)

编译器将实现前者类似

PUSHAL I(SP)
CALL   func1

而后者喜欢

PUSHL I(SP)
CALL func2

对于原子价值,根本不会有太大差异。改为

struct somestruct 
{
   char buffer [20000] ;
}  ;

在那种情况下

void func3(somestruct * i)

可能比

快得多

void func3(somestruct i)

因为要复制的数据量要大得多。