就像每个函数都放在一个堆栈帧上执行它并在完成后刷新它。因此,任何局部变量都不可用于其他函数。但那么我们如何能够将一个局部变量返回给调用者呢?
int pickMin( int x, int y, int z ) {
int min = x ;
if ( y < min )
min = y ;
if ( z < min )
min = z ;
return min ; }
上面的代码工作正常。但是在下面的代码中,编译器确实给出了一条警告信息 - &#34; warning: function returns address of local variable [-Wreturn-local-addr] return a;
&#34;但它最后会打印一个垃圾值,我认为这很好,因为变量已经被刷新了。但为什么在ABOVE计划中没有发生这种情况?!我的意思是,它也应该给我一个垃圾值。而且,我知道下面代码中的问题可以使用malloc
来解决,然后返回该值。 :)
int *returnarray(){
int a[10]; int i;
for(i=0;i<10;++i){
a[i] = i;
}return a;}
答案 0 :(得分:5)
C按值传递所有内容。在您的第一个代码段中,return min
会返回int
个变量。它的值被返回。第二个片段由return
和一个数组名称组成,它会衰减成指针
返回的值是本地变量的内存地址。但是,此变量存在的函数已返回,并且访问此函数使用的内存然后调用未定义的行为。
处理这种情况的方法(即:需要返回一个数组)要么是将目标数组作为参数传递给函数,要么是使用malloc
分配内存并返回该指针。
堆内存有点慢,更容易出错,并且需要你照顾它。不过,here's an example of both approaches
create_fill
分配,分配并返回一个指向堆内存的指针,fill_array
不返回任何内容,但是要求你传递一个数组(衰减成指针),最大长度为填。优点是:堆栈内存不需要太多关注,并且将超过堆。
答案 1 :(得分:2)
return
语句完全符合:它复制变量的值,并将其保留在堆栈顶部,以便调用函数可以使用它。现在,在C中,这适用于简单的值,而不是数组,因为你的&#34;数组变量&#34; a
实际上只是其第一个值的地址。
答案 2 :(得分:2)
首先,仔细阅读call stack wikipage。上面有漂亮的照片。另请参阅x86 calling conventions wikipage。
然后,结果(某些C函数)经常在返回时通过寄存器(或者,对于大struct
- s,在调用者分配的堆栈空间中)。
详情为ABI具体。对于x86-64上的Linux(64位),x86-64 ABI提到%rax
寄存器返回结果(通常情况下,但当结果为struct
时,调用者通过它的地址)。
答案 3 :(得分:0)
在第一种情况下,您返回变量的值。
然而,在第二种情况下,您返回一个局部变量的地址,正如您所说的那样,其他函数不可用。在C中,数组的名称是该数组的基址。因此在第二种情况下,“数组的基地址”被复制到任何变量/指针,该变量/指针被赋予该函数的返回值