我试图理解C语言,更具体地说是关于内存管理。我有一个函数func
,它接受一个参数,一个int指针。如果我使用int i
而不是int *i
,则会分配更多内存,因为该值将被复制。由于我知道func1
和func2
都不会更改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);
}
答案 0 :(得分:2)
这可能是特定于编译器的(您可以查看C规范以确定),但是应该在函数的调用堆栈上分配整数参数。每次调用该函数时,都会分配额外的4个字节,以便在函数返回时释放。
对于函数的引用版本,它将在每个函数调用上为int指针分配空间。根据您的机器,可能更大,更小或与int相同。将sizeof(int)
与sizeof(int*)
进行比较,看看哪个更大。
答案 1 :(得分:2)
让我们来谈谈存储持续时间,它是由变量命名的对象(执行环境中的数据存储区域,其内容可以表示值)的持续时间。没有显式存储持续时间或存储持续时间auto
或register
的函数参数和局部变量具有自动存储持续时间。也就是说,它们是在声明时创建的,并在它们被销毁时创建包含它们的函数返回。
在函数调用中,为参数指定的值将复制到表示函数定义中的参数的自动变量中。这些变量在函数返回时被销毁,所以除非你递归地调用自己,否则你不会积累大量的内存。你不应该关心int
和int*
的大小之间的差异,除非你有很多这些。如有疑问,请在发现问题时查看并更改代码。
答案 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)
因为要复制的数据量要大得多。