堆栈帧内存分配

时间:2014-09-02 13:38:27

标签: c stack

就像每个函数都放在一个堆栈帧上执行它并在完成后刷新它。因此,任何局部变量都不可用于其他函数。但那么我们如何能够将一个局部变量返回给调用者呢?

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

4 个答案:

答案 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时,调用者通过它的地址)。

原则上,我认为C99标准中没有任何内容需要堆栈,但我知道没有调用堆栈的C实现(通常是处理器堆栈,即通过{{3} })。

答案 3 :(得分:0)

在第一种情况下,您返回变量的值。

然而,在第二种情况下,您返回一个局部变量的地址,正如您所说的那样,其他函数不可用。在C中,数组的名称是该数组的基址。因此在第二种情况下,“数组的基地址”被复制到任何变量/指针,该变量/指针被赋予该函数的返回值